# 【BZOJ 3172】 [Tjoi2013]单词

3
a
aa
aaa

## Sample Output

6
3
1

fail树的DP
AC自动机的性质，fail指针指向的地方保证前缀相同，所以倒着跑DP就好了
 1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<algorithm>
5 #include<cmath>
6 #define ll long long
7 #define inf 1000000000
8 #define mod 1000000007
9 const int N=1000005;
10 struct acm{
11     int cnt;
12     int next[1000005][26],sum[1000005],fail[1000005],q[1000005];
13     char ch[1000005];
14     acm(){
15         cnt=1;
16         for (int i=0;i<26;i++) next[0][i]=1;
17     }
18     void ins(int &pos){
19         int now=1;
20         scanf("%s",ch);
21         int n=strlen(ch);
22         for (int i=0;i<n;i++){
23             if(!next[now][ch[i]-'a'])
24             next[now][ch[i]-'a']=++cnt;
25             now=next[now][ch[i]-'a'];
26             sum[now]++;
27         }
28         pos=now;
29     }
30     void buildfail(){
32         q[0]=1,fail[1]=0;
35             for(int i=0;i<26;i++){
36                 int v=next[now][i];
37                 if(!v) continue;
38                 int k=fail[now];
39                 while(!next[k][i]) k=fail[k];
40                 fail[v]=next[k][i];
41                 q[tail++]=v;
42             }
43         }
44          for(int i=tail-1;i>=0;i--)
45             sum[fail[q[i]]]+=sum[q[i]];//就是这里啦！！！
46     }
47 }acm;
48 int n,pos[N];
49 int main(){
50     scanf("%d",&n);
51     for(int i=1;i<=n;i++) acm.ins(pos[i]);
52     acm.buildfail();
53     for (int i=1;i<=n;i++) printf("%d\n",acm.sum[pos[i]]);
54 }

posted @ 2016-02-20 07:43  Alisahhh  阅读(157)  评论(0编辑  收藏  举报