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