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

    #include <bits/stdc++.h>
    #define inf 2333333333333333
    #define N 2000010
    #define p(a) putchar(a)
    #define For(i,a,b) for(int i=a;i<=b;++i)
    //by war
    //2020.7.24
    using namespace std;
    long long n,ans;
    char s[N];
    void in(int &x){
        int y=1;char c=getchar();x=0;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        x*=y;
    }
    void o(int x){
        if(x<0){p('-');x=-x;}
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    
    struct Node{
        int tr[26];
        int len,fa;
        Node(){memset(tr,0,sizeof tr);len=fa=0;}
    }a[N];
    
    struct node{
        int n;
        node *next;
    }*e[N];
    
    struct SAM{
        int las=1,tot=1;
        long long f[N];
    
        void push(int x,int y){
            node *p;
            p=new node();
            p->n=y;
            if(e[x]==0)
                e[x]=p;
            else{
                p->next=e[x]->next;
                e[x]->next=p;
            }
        }
    
        void add(int c){
            int p=las,np=las=++tot;f[tot]=1;
            a[np].len=a[p].len+1;
            for(;p&&!a[p].tr[c];p=a[p].fa) a[p].tr[c]=np;
            if(!p) a[np].fa=1;
            else{
                int q=a[p].tr[c];
                if(a[q].len==a[p].len+1) a[np].fa=q;
                else{
                    int nq=++tot;
                    a[nq]=a[q];a[nq].len=a[p].len+1;
                    a[q].fa=a[np].fa=nq;
                    for(;p&&a[p].tr[c]==q;p=a[p].fa)a[p].tr[c]=nq;
                }
            }
        }
        void dfs(int x){
            for(node *i=e[x];i;i=i->next){
                dfs(i->n);
                f[x]+=f[i->n];
            }
            if(f[x]!=1) ans=max(ans,f[x]*a[x].len);
        }
    
        void deal(){
            For(i,1,n) add(s[i]-'a');
            For(i,2,tot) push(a[i].fa,i);
            dfs(1);
            o(ans);p('
    ');
        }
    
    }sam;
    
    signed main(){
        scanf("%s",s+1);
        n=(int)strlen(s+1);
        sam.deal();
        return 0;
    }
  • 相关阅读:
    [玩]用安卓手机搭建免费Linux服务器
    SSM自学教程
    outlook 2016 系列1--收件归类
    软件开发流程模型
    Android P系统编译之使用PRODUCT_COPY_FILES拷贝文件或文件夹
    车载系统交互的三秒原则
    同理心地图
    Excel 操作
    Android中5种最常见的内存泄漏问题以及解决办法
    android动画相关
  • 原文地址:https://www.cnblogs.com/war1111/p/13372407.html
Copyright © 2011-2022 走看看