BZOJ 3676 (APIO2014)回文串 题解

这题原来的做法是啥我不知道,我只知道自从回文树出来后这题就变成了模板题。。

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

 

posted @ 2015-04-11 23:11  lowsfish  阅读(242)  评论(0编辑  收藏  举报