BZOJ3676:[Apio2014]回文串

3676: [Apio2014]回文串

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 2665  Solved: 1164
[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

思路{回文自动机裸题啊!直接构出回文自动机统计本质不同的串分别有多少个,然后一一比较就可以了。}

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1<<30)
#define il inline
#define RG register
#define LL long long
#define maxx 300010
using namespace std;
char s[maxx];int nxt[maxx][28],cnt[maxx],f[maxx],num[maxx],len[maxx],l,cc;LL Ans;
il void Insert(RG int n,RG int c){
	RG int P=l;while(s[n-len[P]-1]!=s[n])P=f[P];
	if(!nxt[P][c]){
		len[++cc]=len[P]+2;RG int pp=f[P];
		while(s[n-len[pp]-1]!=s[n])pp=f[pp];
		f[cc]=nxt[pp][c],nxt[P][c]=cc;
	}l=nxt[P][c];cnt[l]++;
}
il void count(){for(RG int i=cc;i!=1;--i)cnt[f[i]]+=cnt[i];}
il void getans(){for(RG int i=cc;i!=1;i--)Ans=max(Ans,(LL)len[i]*cnt[i]);printf("%lld",Ans);}
il void work(){
	scanf("%s",s+1);RG int LEN=strlen(s+1);f[0]=1,len[++cc]=-1;
	for(RG int i=1;i<=LEN;++i)Insert(i,s[i]-'a'+1);count();getans();
}
int main(){
    work();
    return 0;
}

 

posted @ 2017-07-09 16:45  QYP_2002  阅读(251)  评论(0编辑  收藏  举报