zoukankan      html  css  js  c++  java
  • JDOJ 2939: Suffix Automaton 广义后缀自动机_统计子串

    建立广义后缀自动机,对每个节点都建立各自的 $Parent$ 数组.

    这样方便统计,不会出现统计错误.

    考虑新加入一个字符.

    1 这条转移边已经存在,显然对答案没有贡献.

    2 这条转移边不存在,贡献即为 $dis[np]-dis[f[np][id]]$

    考虑一下为什么 2 是对的.

    当新建一个节点时,新加入的子串在后缀自动机上体现为边跳边新连的那些转移边,由于这些

    点都是祖父关系,故直接剪掉最上方的父亲的最大长度即可.

    Code:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define setIO(s) freopen(s".in","r",stdin)
    #define maxn 600000
    #define N 30
    #define ll long long
    using namespace std;
    char str[maxn];
    int last=1,tot=1,n,m;
    int ch[maxn][N],cnt[maxn][2],f[maxn][7],dis[maxn],rk[maxn];
    long long C[maxn],ans;
    void ins(int c,int id){
        int np=++tot,p=last; last=np;
        if(ch[p][c]){
            int q=ch[p][c];
            if(dis[q]==dis[p]+1) last=q;
            else {
                int nq=++tot; last=nq;
                f[nq][id]=f[q][id],dis[nq]=dis[p]+1;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                f[q][id]=nq;
                while(p&&ch[p][c]==q) ch[p][c]=nq,p=f[p][id];
            }
        }
        else{
            dis[np]=dis[p]+1;
            while(p&&!ch[p][c]) {  ch[p][c]=np,p=f[p][id]; }
            if(!p) f[np][id]=1;
            else{
                int q=ch[p][c],nq;
                if(dis[q]==dis[p]+1) f[np][id]=q;
                else{
                    nq=++tot;
                    dis[nq]=dis[p]+1;
                    memcpy(ch[nq],ch[q],sizeof(ch[q]));
                    f[nq][id]=f[q][id],f[q][id]=f[np][id]=nq;
                    while(p&&ch[p][c]==q) ch[p][c]=nq,p=f[p][id];
                }
            }
            ans+=(dis[np]-dis[f[np][id]]); 
        }
    }
    int main(){
        //setIO("input");
        int t; scanf("%d",&t);
        while(t--)
        {
            scanf("%s",str),n=strlen(str);
            for(int i=0;i<n;++i) ins(str[i]-'a',0),printf("%lld
    ",ans); 
            last = 1; 
        }
        return 0; 
    
    }
    

      

  • 相关阅读:
    C++中整型变量的存储大小和范围
    A1038 Recover the Smallest Number (30 分)
    A1067 Sort with Swap(0, i) (25 分)
    A1037 Magic Coupon (25 分)
    A1033 To Fill or Not to Fill (25 分)
    A1070 Mooncake (25 分)
    js 获取控件
    C#代码对SQL数据库添加表或者视图
    JS 动态操作表格
    jQuery取得下拉框选择的文本与值
  • 原文地址:https://www.cnblogs.com/guangheli/p/10304367.html
Copyright © 2011-2022 走看看