BZOJ 3676 (APIO2014)回文串 题解
这题原来的做法是啥我不知道,我只知道自从回文树出来后这题就变成了模板题。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 const int MAXN=300000+5; 5 const int SIGMA_SIZE=26; 6 typedef long long LL; 7 struct Node{ 8 Node* go[SIGMA_SIZE],*fail; 9 int cnt,num,len; //本题中num(代表当前结点含有的本质不同回文串个数)可不保存 10 Node():fail(0) {cnt=num=len=0;memset(go,0,sizeof go);} 11 }; 12 Node mem[MAXN],*cur=mem; 13 Node* last; 14 Node* root0,*root1; 15 void init() 16 { 17 cur=mem; 18 root0=cur++; 19 root1=cur++; 20 root1->len=-1; 21 root0->fail=root1; 22 last=root1; 23 } 24 inline Node* newNode(int len) 25 { 26 cur->len=len; 27 return cur++; 28 } 29 char s[MAXN]; 30 int p=0; 31 inline Node* getFail(Node* t) 32 { 33 while(s[p- t->len -1]!=s[p]) t=t->fail; 34 return t; 35 } 36 inline void extend(int w) 37 { 38 ++p; 39 Node* t=getFail(last); 40 if(!t->go[w]) 41 { 42 Node* nt=newNode(t->len+2); 43 t->go[w]=nt; 44 if(t==root1) nt->fail=root0; 45 else nt->fail=getFail(t->fail)->go[w]; 46 nt->num=nt->fail->num+1; 47 } 48 (last=t->go[w])->cnt++; 49 } 50 LL ans=0; 51 void count() 52 { 53 for(Node* t=cur-1;t>=mem+2;--t) 54 { 55 t->fail->cnt+=t->cnt; 56 ans=std::max(ans,(LL)t->len*t->cnt); 57 } 58 } 59 int main() 60 { 61 //freopen("1.in","r",stdin); 62 scanf("%s",s+1); 63 init(); 64 int n=strlen(s+1); 65 s[0]='a'-1; 66 for(int i=1;i<=n;++i) extend(s[i]-'a'); 67 count(); 68 printf("%lld\n",ans); 69 return 0; 70 }