刚开始把题意理解错了囧
题意:给定n个字符串,求每个字符串在其他字符串中出现的次数之和
【题解】
首先肯定要建立AC自动机若单词i与j相同(i<j),就用链表把j接到i的后面,AC自动机的词尾结点上记录该词第一次出现的序号,即可
【代码】
字典树该建多大我真的不知道。。。
#include<stdio.h> #include<stdlib.h> #include<string.h> int ch[1000005][30],val[1000005],f[1000005],sum[1000005],q[1000005],lastnum[1000005],ans[1000005]; char s[1000005]; int sz=0; void tj(int num) { int u=0,i,len=strlen(s); for(i=0;i<len;i++) { if(ch[u][s[i]-96]==0) ch[u][s[i]-96]=++sz; u=ch[u][s[i]-96]; sum[u]++; } if(val[u]==0) val[u]=lastnum[num]=num; else lastnum[num]=val[u]; } void build() { int head=0,tail=0,u,i; for(i=1;i<=26;i++) if(ch[0][i]>0) q[tail++]=ch[0][i]; while(head<tail) { for(i=1;i<=26;i++) if(ch[q[head]][i]>0) { q[tail++]=ch[q[head]][i]; u=f[q[head]]; while(u>0&&ch[u][i]==0) u=f[u]; f[ ch[q[head]][i] ]=ch[u][i]; } head++; } for(i=tail-1;i>=0;i--) { if(val[q[i]]>0) ans[val[q[i]]]=sum[q[i]]; sum[f[q[i]]]+=sum[q[i]]; } } int main() { int n,i; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%s",s); tj(i); } build(); for(i=1;i<=n;i++) printf("%d\n",ans[lastnum[i]]); return 0; }