Tsinsen 最长双回文串

求最长双回文串,正反建回文树求最大。

题目链接:http://www.tsinsen.com/ViewGProblem.page?gpid=A1280

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+5;
 4 const int M=26;
 5 
 6 struct Palindromic_Tree{
 7     int nex[N][M];
 8     int fail[N];
 9     int cnt[N];
10     int num[N];
11     int len[N];
12     int S[N];
13     int last;
14     int n;
15     int p;
16     
17     int newnode(int l)
18     {
19         for(int i=0;i<M;++i)nex[p][i]=0;
20         cnt[p]=0;
21         num[p]=0;
22         len[p]=l;
23         return p++;
24     }
25     
26     void init()
27     {
28         p=0;
29         newnode(0);
30         newnode(-1);
31         last=0;
32         n=0;
33         S[n]=-1;
34         fail[0]=1;
35     }
36     
37     int get_fail(int x){
38         while(S[n-len[x]-1]!=S[n])x=fail[x];
39         return x;
40     }
41     
42     int add(int c){
43         c-='a';
44         S[++n]=c;
45         int cur=get_fail(last);
46         if(!nex[cur][c]){
47             int now=newnode(len[cur]+2);
48             fail[now]=nex[get_fail(fail[cur])][c];
49             nex[cur][c]=now;
50             num[now]=num[fail[now]]+1;
51         }
52         last=nex[cur][c];
53         cnt[last]++;
54         return len[last];
55     }
56     
57     void count(){
58         for(int i=p-1;i>=0;--i)cnt[fail[i]]+=cnt[i];
59     }
60 }T;
61 char s[N];
62 int l[N];
63 void solve()
64 {
65     T.init();
66     int ll=strlen(s);
67     for(int i=ll-1;i>=0;--i)
68     {
69         l[i]=T.add(s[i]);
70     }
71     T.init();int ans=0;
72     for(int i=0;i<ll-1;++i)
73     {
74         int tmp=T.add(s[i]);ans=max(ans,l[i+1]+tmp);
75     }
76     printf("%d\n",ans);
77 }
78 int main()
79 {
80     while(~scanf("%s",s))solve();
81     return 0;
82 }

 

posted @ 2018-01-10 21:44  大奕哥&VANE  阅读(187)  评论(0编辑  收藏  举报