BZOJ 3676 回文串

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
回文自动机裸题。。。

对于每一个节点直接用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);
}






posted @ 2017-07-09 21:00  cooook  阅读(101)  评论(0编辑  收藏  举报