結果
| 問題 |
No.430 文字列検索
|
| コンテスト | |
| ユーザー |
shibh308
|
| 提出日時 | 2024-02-21 13:29:52 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 45 ms / 2,000 ms |
| コード長 | 2,728 bytes |
| コンパイル時間 | 11,449 ms |
| コンパイル使用メモリ | 292,832 KB |
| 最終ジャッジ日時 | 2025-02-19 18:33:25 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 14 |
ソースコード
#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;
//#include "../common.hpp"
// ==HEADER==
// VERIFIED: NO
// ==CONTENT==
struct SuffixAutomaton{
struct State{
int len,link;
bool pref; // prefixを含むか
map<char,int> nex;
State(int len,int link,bool pref) : len(len),link(link),pref(pref){}
};
vector<State> st;
SuffixAutomaton() {
st.emplace_back(0,-1,0);
}
int process(int lst, char c) { // lst: node idx
int cur = st.size();
int p = lst;
int q = 0;
while (p != -1 && !st[p].nex.count(c)) {
st[p].nex[c] = cur;
p = st[p].link;
}
if (p != lst) st.emplace_back(0,0,0);
if (p != -1) {
q = st[p].nex[c];
if (st[p].len+1 != st[q].len) {
int clone = st.size();
st.emplace_back(st[p].len+1, st[q].link, 0);
st[clone].nex = st[q].nex;
st[q].link=clone;
while (p != -1 && st[p].nex[c] == q) {
st[p].nex[c] = clone;
p = st[p].link;
}
if (p != lst) q = clone;
else cur = clone;
}
}
st[cur] = State(st[lst].len+1, q, 1);
return cur;
}
};
bool solve(){
string s;
int m;
cin >> s >> m;
vector<string> t(m);
for(int i = 0; i < m; ++i){
cin >> t[i];
}
SuffixAutomaton sa;
int idx = 0;
for(int i = 0; i < s.size(); ++i){
idx = sa.process(idx, s[i]);
}
idx = sa.process(idx, 0);
vector<int> counts(sa.st.size(), 0);
counts[idx] = 1;
vector<int> in(sa.st.size(), 0);
for(int i = 0; i < sa.st.size(); ++i){
for(auto [c, j] : sa.st[i].nex){
++in[j];
}
}
queue<int> que;
que.emplace(0);
vector<int> tps;
while(!que.empty()){
int x = que.front();
tps.emplace_back(x);
que.pop();
for(auto [c, y] : sa.st[x].nex){
if(--in[y] == 0){
que.emplace(y);
}
}
}
reverse(tps.begin(), tps.end());
for(auto x : tps){
for(auto [c, y]: sa.st[x].nex){
counts[x] += counts[y];
}
}
// for(int i = 0; i < sa.st.size(); ++i){
// cout << counts[i] << " \n"[i + 1 == sa.st.size()];
// }
i64 ans = 0;
for(auto& w : t){
int x = 0;
for(auto c : w){
if(sa.st[x].nex.find(c) == sa.st[x].nex.end()){
x = -1;
break;
}
x = sa.st[x].nex[c];
}
if(x == -1){
continue;
}
ans += counts[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();
}
}
shibh308