• 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
    ",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
    ",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)?' ':'
    ');
        } 
        
        
    }
  • 相关阅读:
    X lvm管理:扩展lv、删除pv、lv,删除物理卷PV
    X 如何在Linux中缩小LVM大小(逻辑卷调整)如何在Linux中缩小LVM大小(逻辑卷调整)
    元素和为目标值的子矩阵数量
    完美矩形问题
    桶排序算法
    组合数组合
    求两个有序数组的第k大的数(默认两有序数组都为从小到大)
    二叉树的遍历
    卡特兰数
    二叉排序树
  • 原文地址:https://www.cnblogs.com/isakovsky/p/11261531.html
Copyright © 2020-2023  润新知