bzoj3172 [Tjoi2013]单词
构造AC自动机
BFS更新答案
由于做完fail后有BFS序,直接用就可以了
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n; 34 char s[1000010]; 35 int ch[1000010][26],ed,wei[222],sum[1000010],pre[1000010],sta[1000010],top; 36 void add(char *s,int id) 37 { 38 int x=0,len=strlen(s); 39 re(i,0,len-1) 40 { 41 int c=s[i]-'a'; 42 if(!ch[x][c])ch[x][c]=++ed; 43 x=ch[x][c]; 44 sum[x]++; 45 } 46 wei[id]=x; 47 } 48 queue<int>h; 49 void getfail() 50 { 51 re(i,0,25)if(ch[0][i]) 52 { 53 h.push(ch[0][i]); 54 pre[ch[0][i]]=0; 55 } 56 while(!h.empty()) 57 { 58 int x=h.front();h.pop(); 59 sta[++top]=x; 60 re(i,0,25) 61 { 62 if(!ch[x][i]) 63 { 64 ch[x][i]=ch[pre[x]][i]; 65 continue; 66 } 67 int v=ch[x][i]; 68 int k=pre[x]; 69 pre[v]=ch[k][i]; 70 h.push(v); 71 } 72 } 73 } 74 int main() 75 { 76 inin(n); 77 re(i,1,n) 78 { 79 strin(s); 80 add(s,i); 81 } 82 getfail(); 83 while(top) 84 sum[pre[sta[top]]]+=sum[sta[top]],top--; 85 re(i,1,n)printf("%d\n",sum[wei[i]]); 86 return 0; 87 }