結果
| 問題 |
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;
}
ei1333333