BZOJ 3676 回文串
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); }