zoukankan      html  css  js  c++  java
  • P3804 【模板】后缀自动机

    思路

    很水的后缀自动机
    找到最长的大小不为1的endpos与maxlen的乘积即可

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int MAXN = 1000100*2;
    int trans[MAXN][26],suflink[MAXN],maxlen[MAXN],endpos[MAXN],ispre[MAXN],in[MAXN],n,cnt;
    char s[MAXN];
    int new_state(int _maxlen,int *_trans,int _suflink){
        ++cnt;
        maxlen[cnt]=_maxlen;
        if(_trans)
            for(int i=0;i<26;i++)
                trans[cnt][i]=_trans[i];
        suflink[cnt]=_suflink;
        return cnt;
    }
    int add_len(int u,int c){
        int z=new_state(maxlen[u]+1,NULL,0);
        ispre[z]=1;
        while(u&&(!trans[u][c])){
            trans[u][c]=z;
            u=suflink[u];
        }
        if(!u){
            suflink[z]=1;
            return z;
        }
        int v= trans[u][c];
        if(maxlen[v]==maxlen[u]+1){
            suflink[z]=v;
            return z;
        }
        int y=new_state(maxlen[u]+1,trans[v],suflink[v]);
        suflink[v]=suflink[z]=y;
        while(u&&trans[u][c]==v){
            trans[u][c]=y;
            u=suflink[u];
        }
        return z;
    }
    queue<int> q;
    int main(){
        scanf("%s",s+1);
        n=strlen(s+1);
        int pre=1;
        cnt=1;
        for(int i=1;i<=n;i++)
            pre=add_len(pre,s[i]-'a');
        for(int i=1;i<=cnt;i++)
            in[suflink[i]]++;
        for(int i=1;i<=cnt;i++) 
            if(!in[i])
                q.push(i);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            endpos[x]+=ispre[x];
            endpos[suflink[x]]+=endpos[x];
            in[suflink[x]]--;
            if(!in[suflink[x]])
                q.push(suflink[x]);
        }
        // for(int i=1;i<=cnt;i++)
        //     printf("%d %d!
    ",endpos[i],maxlen[i]);
        int ans=0;
        for(int i=1;i<=cnt;i++)
            if(endpos[i]>1)
                ans=max(ans,endpos[i]*maxlen[i]);
        printf("%d
    ",ans);
        return 0;   
    }
    
  • 相关阅读:
    51 Nod 1068 Bash游戏v3
    51 Nod Bash 游戏v2
    51 Nod 1073 约瑟夫环
    UVA 12063 Zeros and ones 一道需要好好体会的好题
    51 Nod 1161 Partial sums
    2018中国大学生程序设计竞赛
    UVA 11971 Polygon
    UVA 10900 So do you want to be a 2^n-aire?
    UVA 11346 Possibility
    python with as 的用法
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10474547.html
Copyright © 2011-2022 走看看