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 }
View Code

 

posted @ 2018-03-15 16:19  鲸头鹳  阅读(107)  评论(0编辑  收藏  举报