Description
考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出
现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最
大出现值。
Input
输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。
Output
输出一个整数,为逝查回文子串的最大出现值。
Sample Input
【样例输入l】
abacaba
【样例输入2]
www
abacaba
【样例输入2]
www
Sample Output
【样例输出l】
7
【样例输出2]
4
回文自动机裸题。。。
7
【样例输出2]
4
对于每一个节点直接用NUM[i]*len[i]更新Ans,num的真实值为还要再用类似拓扑序的东西再统计一下
#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 300010
using namespace std;
typedef long long ll;
char s[MAXN];
int ch[MAXN][26],tot,len[MAXN],cnt[MAXN],fail[MAXN],now,n,rt,last;
ll ans;
int newnode(int x){
len[tot]=x;
return tot++;
}
inline int get_fail(int x,int n){
while(s[n-len[x]-1]!=s[n])x=fail[x];
return x;
}
int main(){
gets(s+1);
s[0]=-1;newnode(0);newnode(-1);
fail[0]=1;
for(n=1;s[n];n++){
s[n]-='a';
rt=get_fail(last,n);
if(!ch[rt][s[n]]){
now=newnode(len[rt]+2);
fail[now]=ch[get_fail(fail[rt],n)][s[n]];
ch[rt][s[n]]=now;
}
cnt[last=ch[rt][s[n]]]++;
}
for(int i=tot-1;i>0;i--)
cnt[fail[i]]+=cnt[i],ans=max(ans,(ll)cnt[i]*(ll)len[i]);
printf("%lld\n",ans);
}