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;
    }
  • 相关阅读:
    存储器类型区分
    语言基础(25):容器与算法
    X11-forwarding
    语言基础(24):句柄类
    Markdown(2):流程图
    剑指offer-树的子结构
    剑指offer-判断链表是否有环
    剑指offer-求链表的中间结点
    剑指offer-合并两个排序的链表
    剑指offer-反转链表
  • 原文地址:https://www.cnblogs.com/war1111/p/13372407.html
Copyright © 2011-2022 走看看