結果
問題 | No.430 文字列検索 |
ユーザー | shibh308 |
提出日時 | 2024-02-21 13:13:28 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 19 ms / 2,000 ms |
コード長 | 2,516 bytes |
コンパイル時間 | 3,828 ms |
コンパイル使用メモリ | 243,596 KB |
実行使用メモリ | 6,824 KB |
最終ジャッジ日時 | 2024-11-10 01:10:14 |
合計ジャッジ時間 | 3,962 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 19 ms
6,820 KB |
testcase_02 | AC | 6 ms
6,820 KB |
testcase_03 | AC | 6 ms
6,820 KB |
testcase_04 | AC | 2 ms
6,824 KB |
testcase_05 | AC | 2 ms
6,816 KB |
testcase_06 | AC | 1 ms
6,820 KB |
testcase_07 | AC | 1 ms
6,820 KB |
testcase_08 | AC | 4 ms
6,820 KB |
testcase_09 | AC | 2 ms
6,820 KB |
testcase_10 | AC | 2 ms
6,816 KB |
testcase_11 | AC | 12 ms
6,816 KB |
testcase_12 | AC | 13 ms
6,816 KB |
testcase_13 | AC | 12 ms
6,816 KB |
testcase_14 | AC | 10 ms
6,816 KB |
testcase_15 | AC | 8 ms
6,820 KB |
testcase_16 | AC | 8 ms
6,820 KB |
testcase_17 | AC | 8 ms
6,816 KB |
ソースコード
#ifndef LOCAL #pragma GCC target("arch=x86-64-v3") // judge: v4 or cascadelake(←最後の一投で試すレベルでv4と差がないと思ってる) #pragma GCC optimize("Ofast") #endif #include <bits/stdc++.h> using namespace std; using i64 = long long; struct Trie{ vector<map<char,int>> ch; vector<int> slink, depth; Trie() : ch(1), depth(1, 0){} int add(int idx, char c){ auto it = ch[idx].find(c); if(it == ch[idx].end()){ ch.emplace_back(); depth.emplace_back(depth[idx] + 1); return ch[idx][c] = ch.size() - 1; } return it->second; } int insert(string s){ int idx = 0; for(auto c : s){ idx = add(idx, c); } return idx; } void build(){ slink.resize(ch.size(), 0); queue<int> que; for(auto [_, k] : ch[0]){ slink[k] = 0; que.emplace(k); } while(!que.empty()){ int x = que.front(); que.pop(); for(auto [c, y] : ch[x]){ int xx = slink[x]; while(xx && ch[xx].find(c) == ch[xx].end())xx = slink[xx]; auto it = ch[xx].find(c); slink[y] = it == ch[xx].end() ? 0 : it->second; que.emplace(y); } } } vector<int> search(string s){ vector<int> idxes(s.size() + 1, 0); int idx = 0; for (int i = 0; i < s.size(); ++i) { while(idx && ch[idx].find(s[i]) == ch[idx].end())idx = slink[idx]; auto it = ch[idx].find(s[i]); if(it != ch[idx].end())idx = it->second; idxes[i + 1] = idx; } return idxes; // array of maximal reach length } }; bool solve(){ string s; int m; cin >> s >> m; vector<string> t(m); for(int i = 0; i < m; ++i){ cin >> t[i]; } Trie trie; vector<int> v; for(int i = 0; i < m; ++i){ v.emplace_back(trie.insert(t[i])); } trie.build(); auto res = trie.search(s); vector<vector<int>> edges(trie.ch.size()); queue<int> que; que.emplace(0); vector<int> tps; while(!que.empty()){ int x = que.front(); que.pop(); tps.emplace_back(x); if(x){ edges[trie.slink[x]].emplace_back(x); } for(auto [c, y] : trie.ch[x]){ que.emplace(y); } } vector<int> w(trie.ch.size()); for(auto x : v)++w[x]; for(auto x : tps){ for(auto y : edges[x]){ w[y] += w[x]; } } i64 ans = 0; for(auto x : res){ ans += w[x]; } cout << ans << endl; return 0; } signed main(){ // cin.tie(0); // cin.sync_with_stdio(0); solve(); exit(0); int t; cin >> t; while(t --> 0){ solve(); } }