AC自动机裸题,真的很裸……
先把前面的 n 个待匹配串存起来,再把后面 m 个模式串构造 AC自动机,然后再一个个询问待匹配串就没了……
1 #include<stdio.h>
2 #include<string.h>
3 #include<queue>
4 using namespace std;
5 const int maxm=600006;
6
7 char s[100005][10005],word[10005];
8 int nxt[maxm][26],tail[maxm],f[maxm],size;
9 int last[maxm];
10
11 int newnode(){
12 memset(nxt[size],0,sizeof(nxt[size]));
13 f[size]=tail[size]=0;
14 return size++;
15 }
16
17 void insert(char s[]){
18 int i,p=0;
19 for(i=0;s[i];i++){
20 int &x=nxt[p][s[i]-'a'];
21 p=x?x:x=newnode();
22 }
23 tail[p]++;
24 }
25
26 void makenxt(){
27 int i;
28 queue<int>q;
29 f[0]=0;
30 for(i=0;i<26;i++){
31 int v=nxt[0][i];
32 if(v){
33 f[v]=last[v]=0;
34 q.push(v);
35 }
36 }
37 while(!q.empty()){
38 int u=q.front();
39 q.pop();
40 for(i=0;i<26;i++){
41 int v=nxt[u][i];
42 if(!v)nxt[u][i]=nxt[f[u]][i];
43 else{
44 q.push(v);
45 f[v]=nxt[f[u]][i];
46 last[v]=tail[f[v]]?f[v]:last[f[v]];
47 }
48 }
49 }
50 }
51
52 int query(char s[]){
53 int ans=0,v=0;
54 for(int i=0;s[i];i++){
55 while(v&&!nxt[v][s[i]-'a'])v=f[v];
56 v=nxt[v][s[i]-'a'];
57 int tmp=v;
58 while(tmp){
59 ans+=tail[tmp];
60 tmp=last[tmp];
61 }
62 }
63 return ans;
64 }
65
66 int main(){
67 int T;
68 scanf("%d",&T);
69 while(T--){
70 int n,m;
71 scanf("%d%d",&n,&m);
72 size=0,newnode();
73 for(int i=0;i<n;++i){
74 scanf("%s",s[i]);
75 }
76 for(int i=0;i<m;++i){
77 scanf("%s",word);
78 insert(word);
79 }
80 makenxt();
81 for(int i=0;i<n;++i){
82 printf("%d
",query(s[i]));
83 }
84 }
85 return 0;
86 }