bzoj3676 回文串【回文树】

来源:互联网 发布:电脑软件怎么卸载 编辑:程序博客网 时间:2024/06/05 03:52

解题思路:

回文树模板题,建好后取每个节点cnt*len的最大值即可。
回文树解析详见:http://blog.csdn.net/u013368721/article/details/42100363
真的好文。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<algorithm>#include<ctime>#include<vector>#include<queue>#define ll long longusing namespace std;int getint(){    int i=0,f=1;char c;    for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());    if(c=='-')c=getchar(),f=-1;    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';    return i*f;}const int N=300005;struct node{    int son[26],fail,cnt,len;}tr[N];int n,tot=-1,last;char s[N];ll ans;int newnode(int l){    tr[++tot].len=l;    return tot;}void Init(){    newnode(0);    newnode(-1);    last=0,tr[0].fail=1,s[0]='#';}int getfail(int x){    while(s[n-tr[x].len-1]!=s[n])        x=tr[x].fail;    return x;}void Insert(char c){    s[++n]=c;    int cur=getfail(last);    if(!tr[cur].son[c-'a'])    {        int now=newnode(tr[cur].len+2);        tr[now].fail=tr[getfail(tr[cur].fail)].son[c-'a'];        tr[cur].son[c-'a']=now;    }    last=tr[cur].son[c-'a'];    tr[last].cnt++;}int main(){    //freopen("lx.in","r",stdin);    char c;    Init();    for(c=getchar();c<'a'||c>'z';c=getchar());    while(c>='a'&&c<='z')        Insert(c),c=getchar();    for(int i=tot;i>=0;i--)tr[tr[i].fail].cnt+=tr[i].cnt;    for(int i=2;i<=tot;i++)ans=max(ans,1ll*tr[i].len*tr[i].cnt);    cout<<ans<<'\n';}
原创粉丝点击