【模板】AC自动机
1 #include<cstdio> 2 #include<algorithm> 3 #include<queue> 4 #include<cstring> 5 #define N 1000010 6 #define rg register 7 using namespace std; 8 int n,ans,tot,c[N][26],val[N],fail[N]; 9 char s[N]; 10 queue<int>q; 11 inline int read(){ 12 int k=0,f=1; char c=getchar(); 13 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 14 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 15 return k*f; 16 } 17 void insert(char *s){ 18 int len=strlen(s),now=0; 19 for(rg int i=0,v;i<len;i++){ 20 if(!c[now][v=s[i]-'a']) c[now][v]=++tot; 21 now=c[now][v]; 22 } 23 val[now]++; 24 } 25 void build(){ 26 for(rg int i=0;i<26;i++)if(c[0][i])fail[c[0][i]]=0,q.push(c[0][i]); 27 while(!q.empty()){ 28 int u=q.front(); q.pop(); 29 for(rg int i=0;i<26;i++) 30 if(c[u][i])fail[c[u][i]]=c[fail[u]][i],q.push(c[u][i]); 31 else c[u][i]=c[fail[u]][i]; 32 } 33 } 34 void query(char *s){ 35 int len=strlen(s),now=0; 36 for(rg int i=0;i<len;i++){ 37 now=c[now][s[i]-'a']; 38 for(rg int t=now;t&&~val[t];t=fail[t])ans+=val[t],val[t]=-1; 39 } 40 } 41 int main(){ 42 n=read(); 43 for(rg int i=1;i<=n;i++) scanf("%s",s),insert(s); 44 build(); 45 scanf("%s",s); query(s); 46 printf("%d\n",ans); 47 return 0; 48 }
洛谷 3808
1 #include<cstdio> 2 #include<algorithm> 3 #include<queue> 4 #include<cstring> 5 #define N 1000010 6 #define rg register 7 using namespace std; 8 int n,ans,tot,mx,c[26][N],fail[N],num[N],l[N],cnt[200]; 9 char s[N],p[200][80]; 10 queue<int>q; 11 inline int read(){ 12 int k=0,f=1; char c=getchar(); 13 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 14 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 15 return k*f; 16 } 17 inline int max(int x,int y){return x>y?x:y;} 18 inline void insert(char *s,int number){ 19 int len=strlen(s),now=0; 20 for(rg int i=0,v;i<len;i++){ 21 if(!c[v=s[i]-'a'][now]) c[v][now]=++tot; 22 now=c[v][now]; 23 } 24 num[now]=number; 25 } 26 inline void build(){ 27 for(rg int i=0;i<26;i++)if(c[i][0])fail[c[i][0]]=0,q.push(c[i][0]); 28 while(!q.empty()){ 29 int u=q.front(); q.pop(); 30 for(rg int i=0;i<26;i++) 31 if(c[i][u]) 32 fail[c[i][u]]=c[i][fail[u]], 33 l[c[i][u]]=num[fail[c[i][u]]]?fail[c[i][u]]:l[fail[c[i][u]]], 34 q.push(c[i][u]); 35 else c[i][u]=c[i][fail[u]]; 36 } 37 } 38 inline void query(char *s){ 39 int len=strlen(s),now=0; 40 for(rg int i=0;i<len;i++){ 41 now=c[s[i]-'a'][now]; 42 for(rg int t=now;t;t=fail[t])cnt[num[t]]++; 43 } 44 } 45 int main(){ 46 while(1){ 47 memset(cnt,0,sizeof(cnt)); 48 memset(num,0,sizeof(num)); 49 memset(l,0,sizeof(l)); 50 memset(c,0,sizeof(c)); tot=0; mx=0; 51 n=read(); if(!n) return 0; 52 for(rg int i=1;i<=n;i++) scanf("%s",p[i]),insert(p[i],i); 53 build(); 54 char ch=getchar(); int now=0; 55 while(ch<'a'||ch>'z') ch=getchar(); 56 while('a'<=ch&&ch<='z'){ 57 now=c[ch-'a'][now]; 58 for(rg int t=now;t;t=l[t]) cnt[num[t]]++; 59 ch=getchar(); 60 } 61 for(rg int i=1;i<=n;i++) mx=max(mx,cnt[i]); 62 printf("%d\n",mx); 63 for(rg int i=1;i<=n;i++) if(cnt[i]==mx) printf("%s\n",p[i]); 64 } 65 return 0; 66 }
洛谷 3796 加强版