BZOJ 3676: [Apio2014]回文串 回文树 回文自动机
http://www.lydsy.com/JudgeOnline/problem.php?id=3676
另一种更简单更快常数更小的写法,很神奇……背板子。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<map> 7 using namespace std; 8 const int maxn=300010; 9 char ch[maxn]; 10 int siz; 11 struct pam{ 12 int sig[26]; 13 int f,len,cnt; 14 }t[maxn]; 15 int tot=1,las=0; 16 long long ans=0; 17 void add(int z,int n){ 18 int p=las; 19 while(ch[n-t[p].len-1]!=ch[n])p=t[p].f; 20 if(!t[p].sig[z]){ 21 int y=++tot;int k=t[p].f; 22 t[y].len=t[p].len+2; 23 while(ch[n-t[k].len-1]!=ch[n])k=t[k].f; 24 t[y].f=t[k].sig[z];t[p].sig[z]=y;//注意这里的顺序是不能调整的 25 } 26 las=t[p].sig[z]; 27 t[las].cnt++; 28 } 29 void solve(){ 30 for(int i=tot;i;i--){ 31 t[t[i].f].cnt+=t[i].cnt; 32 ans=max(ans,(long long )t[i].cnt*t[i].len); 33 } 34 } 35 int main(){ 36 memset(t,0,sizeof(t));t[0].f=t[1].f=1;t[1].len=-1; 37 scanf("%s",ch+1);siz=strlen(ch+1); 38 for(int i=1;i<=siz;i++)add(ch[i]-'a',i); 39 solve(); 40 printf("%lld\n",ans); 41 return 0; 42 }