[bzoj3676]回文串

来源:互联网 发布:ncbi geo数据库 编辑:程序博客网 时间:2024/05/18 18:03

题目描述:
考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出
现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最 大出现值。
分析:回文自动机裸题了。

#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<iostream>using namespace std;typedef long long LL;const int maxn=300010;char s[maxn];struct Palidrome_Tree{    int ch[maxn][26],fail[maxn];    int p,e,last;    int S[maxn],len[maxn],rt[maxn];    void init(){        p=last=0;e=1;        fail[0]=fail[1]=1;        len[1]=-1;        S[0]=-1;    }    int getfail(int o){        while(S[p]!=S[p-len[o]-1]) o=fail[o];        return o;    }    void add(int c){        S[++p]=c;        int cur=getfail(last);        if(!ch[cur][c]){            e++;            fail[e]=ch[getfail(fail[cur])][c];            len[e]=len[cur]+2;            ch[cur][c]=e;        }        last=ch[cur][c];        rt[last]++;    }    LL count(){        LL ans=0;        for(int i=e;i>=1;i--){            rt[fail[i]]+=rt[i];            ans=max(ans,1LL*rt[i]*len[i]);        }        return ans;    }}T;int main(){    scanf("%s",s+1);    int l=strlen(s+1);    T.init();    for(int i=1;i<=l;i++) T.add(s[i]-'a');    printf("%lld",T.count());    return 0;}

^_^

原创粉丝点击