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\n",query(s[i]));
83         }
84     }
85     return 0;
86 }
View Code