bzoj 3676 [Apio2014]回文串 回文自动机

[Apio2014]回文串

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 3428  Solved: 1580
[Submit][Status][Discuss]

Description

考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出 
现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最 
大出现值。 

Input

输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。 

Output


输出一个整数,为逝查回文子串的最大出现值。 

Sample Input

【样例输入l】
abacaba

【样例输入2]
www

Sample Output

【样例输出l】
7

【样例输出2]
4

HINT

 



一个串是回文的,当且仅当它从左到右读和从右到左读完全一样。 

在第一个样例中,回文子串有7个:a,b,c,aba,aca,bacab,abacaba,其中: 

● a出现4次,其出现值为4:1:1=4 

● b出现2次,其出现值为2:1:1=2 

● c出现1次,其出现值为l:1:l=l 

● aba出现2次,其出现值为2:1:3=6 

● aca出现1次,其出现值为1=1:3=3 

●bacab出现1次,其出现值为1:1:5=5 

● abacaba出现1次,其出现值为1:1:7=7 

故最大回文子串出现值为7。 

【数据规模与评分】 

数据满足1≤字符串长度≤300000。

 

Source

 

 题解:回文自动机模板题
 1 #include<cstring>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstdio>
 6 
 7 #define N 300007
 8 #define ll long long
 9 using namespace std;
10 inline int read()
11 {
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
15     return x*f;
16 }
17 
18 int n;ll ans;
19 char ch[N];
20 struct pam
21 {
22     int cnt,last;
23     int c[N][26],fa[N],len[N],siz[N];
24     pam()
25     {
26         cnt=1;
27         fa[0]=fa[1]=1;
28         len[1]=-1;
29     }
30     void extend(int x,int n)
31     {
32         int p=last;
33         while(ch[n-len[p]-1]!=ch[n])p=fa[p];
34         if(!c[p][x])
35         {
36             int now=++cnt,k=fa[p];
37             len[now]=len[p]+2;
38             while(ch[n-len[k]-1]!=ch[n])k=fa[k];
39             fa[now]=c[k][x],c[p][x]=now;
40         }
41         last=c[p][x];
42         siz[last]++;
43     }
44     void solve()
45     {
46         for (int i=cnt;i>=1;i--)
47         {
48             siz[fa[i]]+=siz[i];
49             ans=max(ans,(ll)siz[i]*len[i]);
50         }
51     }
52 }pam;
53 
54 int main()
55 {
56     scanf("%s",ch+1);n=strlen(ch+1);
57     for (int i=1;i<=n;i++)
58         pam.extend(ch[i]-'a',i);
59     pam.solve();
60     printf("%lld\n",ans);
61 }

 

posted @ 2018-04-15 16:07  Kaiser-  阅读(154)  评论(0编辑  收藏  举报