結果
問題 | No.430 文字列検索 |
ユーザー | ei1333333 |
提出日時 | 2016-10-02 22:57:43 |
言語 | C++11 (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 76 ms / 2,000 ms |
コード長 | 2,161 bytes |
コンパイル時間 | 1,259 ms |
コンパイル使用メモリ | 166,508 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-11-10 00:02:42 |
合計ジャッジ時間 | 2,476 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 14 |
ソースコード
#include <bits/stdc++.h> using namespace std; typedef unsigned long long hash_type; struct RollingHash { hash_type base1; vector< hash_type > hash1, pow1; RollingHash() : base1(29LL) { } void init(const string& s) { int n = s.size(); hash1.assign(n + 1, 0); pow1.assign(n + 1, 1); for(int i = 0; i < n; i++) { hash1[i + 1] = (hash1[i] + s[i] - 'A') * base1; pow1[i + 1] = pow1[i] * base1; } } hash_type get(int l, int r) { if(r >= hash1.size()) return (~0); return ((hash1[r] - hash1[l] * pow1[r - l])); } }; RollingHash hashed; int N, M; string S; bool compare(const int& a, const int& b) { int low = 0, high = min(N - a, N - b) + 1; while(high - low > 1) { int mid = (low + high) >> 1; if(hashed.get(a, a + mid) == hashed.get(b, b + mid)) low = mid; else high = mid; } if(low == min(N - a, N - b)) return (low == N - a); return (S[a + low] < S[b + low]); } string T; bool comp(RollingHash& hashed1, const int& b) { int mm = hashed1.hash1.size() - 1; int low = 0, high = min(mm, N - b) + 1; while(high - low > 1) { int mid = (low + high) >> 1; if(hashed1.get(0, mid) == hashed.get(b, b + mid)) low = mid; else high = mid; } if(low == min(mm, N - b)) return (low == mm); return (T[low] < S[b + low]); } int main() { cin >> S; N = S.size(); hashed.init(S); vector< int > idx(S.size()); iota(idx.begin(), idx.end(), 0); sort(idx.begin(), idx.end(), compare); int M; cin >> M; long long ret = 0; while(M--) { cin >> T; RollingHash buff; buff.init(T); hash_type val = buff.get(0, T.size()); int low1 = -1, high1 = S.size() - 1; while(high1 - low1 > 1) { int mid = (low1 + high1) >> 1; if(comp(buff, idx[mid])) high1 = mid; else low1 = mid; } if(val != hashed.get(idx[high1], idx[high1] + T.size())) continue; int low2 = high1, high2 = S.size(); while(high2 - low2 > 1) { int mid = (low2 + high2) >> 1; if(val == hashed.get(idx[mid], idx[mid] + T.size())) low2 = mid; else high2 = mid; } ret += low2 - high1 + 1; } cout << ret << endl; }