• 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;   
    }
    
  • 相关阅读:
    构建之法阅读笔记03
    构建之法阅读笔记02
    构建之法读书笔记01
    梦断代码读书笔记03
    背包九讲问题
    C-01背包问题
    C-最长回文子串(2)
    C-最长回文子串(1)
    C语言顺序栈实现
    带头结点头部插入创建链表
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10474547.html
Copyright © 2020-2023  润新知