hysbz3676 回文串 回文自动机

回文自动机模板题

头铁了一下午hdu6599,最后发现自己的板有问题

先放这里一个正确性得到基本确认的板,过两天肝hdu6599

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<cassert>
#define MAXN 300010
#define LL long long
#define BASE 2LL
#define MOD 1000000007
using namespace std; 

char s[MAXN];
int len;
LL ans[MAXN];

int qpow(int base,int n){
    LL ans=1;
    while(n){
        if(n&1)ans=(ans*base)%MOD;
        base=(1LL*base*base)%MOD;
        n>>=1;
    }
    return ans;
}

struct PTnode{
    int len,fail,son[26];
    LL cnt;//该点对应的回文串出现次数 
    //建完了树,要再跑一遍,cnt才是正确的 
    PTnode(){
        cnt=len=fail=0;
        memset(son,0,sizeof son);
    }
}PTdian[MAXN<<1];

int PTlast,PTnum;

int PTgetfail(int i,int x){
    while(s[i-PTdian[x].len-1]!=s[i]) {
        x=PTdian[x].fail;
    }
    return x;
}

void PTextend(int i,int x){
    int cur=PTgetfail(i,PTlast);
    if(!PTdian[cur].son[x]){
        int now=++PTnum;
        PTdian[now].len=PTdian[cur].len+2;
        PTdian[now].fail=PTdian[PTgetfail(i,PTdian[cur].fail)].son[x];
        PTdian[cur].son[x]=now;
    }
    PTdian[PTdian[cur].son[x]].cnt++;
    PTlast=PTdian[cur].son[x];
}
void PTcount(){
    for(int i=PTnum;i>=2;i--){
        //逆序累加
        PTdian[PTdian[i].fail].cnt+=PTdian[i].cnt;
    }
} 
//int dfs(int l,int index,int hash1,int hash2){
//    if(index>1 && hash1==hash2){
//        ans[PTdian[index].len]+=PTdian[index].cnt;
//    }
//    for(int i=0;i<26;i++){
//        if(PTdian[index].son[i]!=0){
//            LL tmp1=(hash1+i*qpow(BASE,l)%MOD)%MOD;
//            LL tmp2=(BASE*hash2%MOD+i)%MOD;
//            dfs(l+1,PTdian[index].son[i],tmp1,tmp2);
//        }
//    }
//}
//char a[MAXN];
//int dfs1(int depth,int index){
//    //检查回文自动机构造正确性 
//    for(int i=0;i<depth;i++)printf("%c",a[i]);
//    printf(" len:%d siz:%d\n",PTdian[index].len,PTdian[index].cnt);
//    for(int i=0;i<26;i++){
//        if(PTdian[index].son[i]!=0){
//            a[depth]=i+'a';
//            dfs1(depth+1,PTdian[index].son[i]);
//        }
//    }
//}
int main(){
//    freopen("1.txt","r",stdin);
//    freopen("2.txt","w",stdout);
    while(1){
        int rep=scanf("%s",s);
        if(rep==EOF)break;
        len=strlen(s);
        memset(ans,0,sizeof ans);memset(PTdian,0,sizeof PTdian);
        PTlast=PTnum=1;
        PTdian[1].len=-1;
        PTdian[0].fail=PTdian[1].fail=1;
        
        for(int i=0;i<len;i++){
            PTextend(i,s[i]-'a');
        }
        PTcount();
        LL maxx=0;
        for(int i=2;i<=PTnum;i++){
            maxx=max(maxx,1LL*PTdian[i].cnt*PTdian[i].len);
        } 
        printf("%lld\n",maxx);
//        dfs(0,0,0,0);
//        dfs(0,1,0,0);
    //    dfs1(0,0);
    //    dfs1(0,1);
//        for(int i=1;i<=len;i++)printf("%lld%c",ans[i],(i!=len)?' ':'\n');
    } 
    
    
}

 

posted @ 2019-07-28 23:33  Isakovsky  阅读(207)  评论(0编辑  收藏  举报