BZOJ3676: [Apio2014]回文串(回文树)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3676

这叫模版题TAT

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define ll long long
#define maxn 300500
using namespace std;
int cnt[maxn],len[maxn];
ll ans;
int fail[maxn],s[maxn],to[maxn][30];
char ch[maxn];
int tot,n,last,L;
void add(int c){
    s[++n]=c;
    int cur,tmp,now;
    for (cur=last;s[n-len[cur]-1]!=s[n];cur=fail[cur]);
    if (!to[cur][c]){
        len[++tot]=len[cur]+2; now=tot;
        for (tmp=fail[cur];s[n-len[tmp]-1]!=s[n];tmp=fail[tmp]);
        fail[now]=to[tmp][c];
        to[cur][c]=now;
    } last=to[cur][c];
    cnt[last]++;
}
int main(){
    scanf("%s",ch);  L=strlen(ch);
    len[tot=0]=0; len[++tot]=-1;
    fail[0]=1; fail[1]=1; s[0]=-1;
    rep(i,0,L-1) add(ch[i]-'a');
    down(i,tot,2) cnt[fail[i]]+=cnt[i];
    rep(i,2,tot) ans=max(ans,(ll)cnt[i]*len[i]);
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/ctlchild/p/4986851.html