結果
| 問題 |
No.430 文字列検索
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-10-10 21:45:01 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 10 ms / 2,000 ms |
| コード長 | 2,502 bytes |
| コンパイル時間 | 1,751 ms |
| コンパイル使用メモリ | 177,684 KB |
| 実行使用メモリ | 14,464 KB |
| 最終ジャッジ日時 | 2024-11-10 00:10:18 |
| 合計ジャッジ時間 | 2,144 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 14 |
ソースコード
class in {struct my_iterator{int it;const bool rev;explicit constexpr my_iterator(int it_, bool rev=false):it(it_),rev(rev){}int operator*(){return it;}bool operator!=(my_iterator& r){return it!=r.it;}void operator++(){rev?--it:++it;}};const my_iterator i,n;public:explicit constexpr in(int n):i(0),n(n){}explicit constexpr in(int i,int n):i(i,n<i),n(n){}const my_iterator& begin(){return i;}const my_iterator& end(){return n;}};
#include <bits/stdc++.h>
using namespace std;
template<int Code>
struct Node_ {
Node_* next[Code];
Node_* fail;
int num;
explicit Node_() : fail(nullptr), num(0)
{ fill_n(next, Code, nullptr);}
};
typedef Node_<26> node_t;
void constructAC(vector<node_t>& nodes, const vector<string>& patterns) {
node_t* root = &nodes[0];
//Phase 1 (trie)
int count = 0;
for(const auto& s : patterns) {
node_t* cur = root;
for(const char& c : s) {
int k = c - 'A';
if(cur->next[k] == nullptr)
cur->next[k] = &nodes[++count];
cur = cur->next[k];
}
cur->num = 1;
}
//Phase 2 (failue link)
queue<node_t*> que;
for(int i : in(26)) {
if(root->next[i] != nullptr) {
root->next[i]->fail = root;
que.emplace(root->next[i]);
}
else
root->next[i] = root;
}
while(!que.empty()) {
node_t* cur = que.front(); que.pop();
for(int i : in(26)) {
if(cur->next[i] == nullptr) continue;
que.emplace(cur->next[i]);
node_t* f = cur->fail;
while(f->next[i] == nullptr) f = f->fail;
cur->next[i]->fail = f->next[i];
}
}
}
bool used[50010];
int getNum(node_t* cur, node_t* root) {
if(cur == root) return 0;
int id = cur - root;
if(used[id]) return cur->num;
used[id] = true;
cur->num += getNum(cur->fail, root);
return cur->num;
}
int main() {
cin.tie(0);
ios::sync_with_stdio(false);
string s; cin >> s;
int m; cin >> m;
vector<string> patterns(m);
for(auto& x : patterns) cin >> x;
vector<node_t> nodes(m * 10 + 1);
constructAC(nodes, patterns);
node_t* cur = &nodes[0];
int ans = 0;
memset(used, 0, sizeof(used));
for(int i : in(s.size())) {
int k = s[i] - 'A';
while(cur->next[k] == nullptr) cur = cur->fail;
cur = cur->next[k];
ans += getNum(cur, &nodes[0]);
}
cout << ans << endl;
return 0;
}