結果
問題 | No.430 文字列検索 |
ユーザー | mio_h |
提出日時 | 2016-10-10 21:45:01 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.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 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 10 ms
14,384 KB |
testcase_02 | AC | 8 ms
14,336 KB |
testcase_03 | AC | 7 ms
14,320 KB |
testcase_04 | AC | 1 ms
5,248 KB |
testcase_05 | AC | 1 ms
5,248 KB |
testcase_06 | AC | 1 ms
5,248 KB |
testcase_07 | AC | 2 ms
5,248 KB |
testcase_08 | AC | 2 ms
5,248 KB |
testcase_09 | AC | 2 ms
5,248 KB |
testcase_10 | AC | 1 ms
5,248 KB |
testcase_11 | AC | 10 ms
14,348 KB |
testcase_12 | AC | 10 ms
14,336 KB |
testcase_13 | AC | 9 ms
14,336 KB |
testcase_14 | AC | 9 ms
14,460 KB |
testcase_15 | AC | 9 ms
14,464 KB |
testcase_16 | AC | 7 ms
14,444 KB |
testcase_17 | AC | 8 ms
14,464 KB |
ソースコード
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; }