BZOJ 3676: [Apio2014]回文串 回文自动机

 

主要是初始化那里需要注意一下.      

然后不要忘记每次给 $last$ 节点的大小++   

#include <cstdio>  
#include <string> 
#include <cstring>
#include <algorithm>    
#define N 300008 
#define ll long long 
using namespace std;         
char str[N];  
namespace PAM 
{    
    int tot,last;  
    int pre[N],ch[N][26],len[N],ss[N],sz[N];  
    void init() 
    {  
        ss[0]=-1,pre[0]=1,len[1]=-1,tot=1;
        for(int i=1,j=strlen(str+1);i<=j;++i) ss[i]=str[i]-'a';     
    }         
    int newnode(int x) { return len[++tot]=x,tot; }              
    int getfail(int p,int i) 
    {   
        while(ss[i-len[p]-1]!=ss[i]) p=pre[p];      
        return p;   
    }                           
    void extend(int c,int i) 
    {
        int p=getfail(last,i);     
        if(!ch[p][c]) 
        { 
            int q=newnode(len[p]+2);   
            pre[q]=ch[getfail(pre[p],i)][c],ch[p][c]=q;   
        }    
        ++sz[last=ch[p][c]];       
    }
    ll calc() 
    {    
        ll ans=0ll; 
        for(int i=tot;i>=1;--i) ans=max(ans,(ll)sz[i]*len[i]),sz[pre[i]]+=sz[i];   
        return ans; 
    }
}; 
void setIO(string s) { freopen((s+".in").c_str(),"r",stdin); }   
int main() 
{    
    // setIO("input"); 
    int i,j,n; 
    scanf("%s",str+1),n=strlen(str+1);     
    PAM::init();  
    for(i=1;i<=n;++i) PAM::extend(str[i]-'a',i);      
    printf("%lld\n",PAM::calc());  
    return 0; 
}

  

posted @ 2019-02-11 11:37  EM-LGH  阅读(152)  评论(0编辑  收藏  举报