luogu P5357 【模板】AC自动机(二次加强版)
题目大意
给出若干模式串和一个匹配串
求每个模式串在匹配串中出现的个数
题解
所以这题和luogu P3966 [TJOI2013]单词有什么区别,直接跑完,然后统计子树大小就好辣
code:
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define N 200005
#define C 26
using namespace std;
int py[N], size[N], ch[N][C], vis[N], nxt[N], ha[N], n, tot;
string st;
void insert(int id){
int p = 0, len = st.length();
for(int i = 0; i < len; i ++){
if(!ch[p][st[i] - 'a']) ch[p][st[i] - 'a'] = ++ tot;
p = ch[p][st[i] - 'a'];
}
py[id] = p;
}
queue<int> q;
void build(){
for(int i = 0; i < C; i ++) if(ch[0][i]) q.push(ch[0][i]);
while(q.size()){
int u = q.front(); q.pop();
ha[++ ha[0]] = u;
for(int i = 0; i < C; i ++){
if(ch[u][i]){
nxt[ch[u][i]] = ch[nxt[u]][i];
q.push(ch[u][i]);
} else ch[u][i] = ch[nxt[u]][i];
}
}
}
void find(){
int len = st.length(), p = 0;
for(int i = 0; i < len; i ++){//直接跑
p = ch[p][st[i] - 'a'];
size[p] ++;
}
}
int main() {
ios::sync_with_stdio(false);
cin >> n;
for(int i = 1; i <= n; i ++){
cin >> st;
insert(i);
}
build();
cin >> st;
find();
for(int i = ha[0]; i >= 1; i --) size[nxt[ha[i]]] += size[ha[i]];//统计子树大小
for(int i = 1; i <= n; i ++) cout << size[py[i]] << endl;
return 0;
}