BZOJ 4516: [Sdoi2016]生成魔咒 后缀自动机 性质

http://www.lydsy.com/JudgeOnline/problem.php?id=4516

http://blog.csdn.net/doyouseeman/article/details/52245413

后缀自动机的性质应用,求子串种类数。

 

又是自动机写错了查了半天,字符集太大了导致什么都没对拍出来。。。最后肉眼看出来了,我是个zz。

 1 /**************************************************************
 2     Problem: 4516
 3     User: 137shoebills
 4     Language: C++
 5     Result: Accepted
 6     Time:856 ms
 7     Memory:14940 kb
 8 ****************************************************************/
 9  
10 #include<iostream>
11 #include<cstdio>
12 #include<algorithm>
13 #include<cstring>
14 #include<cmath>
15 #include<map>
16 using namespace std;
17 const int maxn=100010;
18 map< int , int >sig[maxn*2];
19 int n;
20 struct nod{
21     int len,f;
22 }t[maxn*2];
23 int la=1,tot=1;
24 long long ans=0;
25 long long getnum(int x){return (long long)(t[x].len-t[t[x].f].len);}
26 void add(int z){
27     int x=++tot;int i=la;
28     t[x].len=t[la].len+1;
29     for(;i&&!sig[i][z];i=t[i].f){
30         sig[i][z]=x;
31     }
32     if(!i){t[x].f=1;ans+=getnum(x);}
33     else{
34         int p=sig[i][z];
35         if(t[p].len==t[i].len+1){t[x].f=p;ans+=getnum(x);}
36         else{
37             int y=++tot;
38             t[y]=t[p];sig[y]=sig[p];
39             t[y].len=t[i].len+1;
40             ans+=getnum(y);ans-=getnum(p);
41             t[p].f=t[x].f=y;
42             ans+=getnum(x)+getnum(p);
43             for(;i&&sig[i][z]==p;i=t[i].f){
44                 sig[i][z]=y;
45             }
46         }
47     }
48     la=x;
49     printf("%lld\n",ans);
50 }
51 int main(){
52     memset(t,0,sizeof(t));
53     scanf("%d",&n);int x;
54     for(int i=1;i<=n;i++){scanf("%d",&x);add(x);}
55     return 0;
56 }
57 
View Code

 

posted @ 2018-03-12 16:20  鲸头鹳  阅读(129)  评论(0编辑  收藏  举报