zoukankan      html  css  js  c++  java
  • CSU-1632 Repeated Substrings[后缀数组求重复出现的子串数目]

     

    评测地址:https://cn.vjudge.net/problem/CSU-1632

    Description

    求字符串中所有出现至少2次的子串个数

    Input

    第一行为一整数T(T<=10)表示用例组数,每组用例占一行为一个长度不超过100000的字符串

    Output

    对于每组用例,输出该串中所有出现至少两次的子串个数

    Sample Input

    3

    aabaab

    aaaaa

    AaAaA

    Sample Output

    5

    4

    5

    Solution

    Ans=summax(height(i)-height(i-1),0)

     

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1e5+5;
    int T,n,ans,c[N],sa[N],tsa[N],trank[N],rank[N],h[N];
    char s[N];
    void DA(int maxx=256){
        memset(c,0,sizeof c);int p;
        for(int i=1;i<=n;i++) c[rank[i]=s[i]]++;
        for(int i=2;i<=maxx;i++) c[i]+=c[i-1];
        for(int i=n;i;i--) sa[c[rank[i]]--]=i;
        trank[sa[1]]=p=1;
        for(int i=2;i<=n;i++){
            if(rank[sa[i]]!=rank[sa[i-1]]) p++;
            trank[sa[i]]=p;
        }
        for(int i=1;i<=n;i++) rank[i]=trank[i];
        for(int k=1;p<n;k<<=1,maxx=p){
            p=0;
            for(int i=n-k+1;i<=n;i++) tsa[++p]=i;
            for(int i=1;i<=n;i++) if(sa[i]>k) tsa[++p]=sa[i]-k;
            memset(c,0,sizeof c);
            for(int i=1;i<=n;i++) trank[i]=rank[tsa[i]];
            for(int i=1;i<=n;i++) c[trank[i]]++;
            for(int i=2;i<=maxx;i++) c[i]+=c[i-1];
            for(int i=n;i;i--) sa[c[trank[i]]--]=tsa[i];
            trank[sa[1]]=p=1;
            for(int i=2;i<=n;i++){
                if(rank[sa[i]]!=rank[sa[i-1]]||rank[sa[i]+k]!=rank[sa[i-1]+k]) p++;
                trank[sa[i]]=p;
            }
            for(int i=1;i<=n;i++) rank[i]=trank[i];
        }
        for(int i=1,k=0;i<=n;i++){
            int j=sa[rank[i]-1];
            while(s[i+k]==s[j+k]) k++;
            h[rank[i]]=k;if(k>0)k--;
        }
    }
    void GO(){
        ans=0;
        for(int i=1;i<=n;i++) if(h[i]>h[i-1]) ans+=h[i]-h[i-1];
        printf("%d
    ",ans);
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%s",s+1);n=strlen(s+1);
            DA();
            GO();
        }
        return 0;
    }

     

     

  • 相关阅读:
    知识体系总结
    计算机基础总结
    Redis总结
    Mysql总结
    JAVA基础总结
    有锁编程
    CAS
    读写自旋锁
    org.apache.log4j.Logger详解
    web.xml 中的listener、 filter、servlet 加载顺序及其详解
  • 原文地址:https://www.cnblogs.com/shenben/p/6537092.html
Copyright © 2011-2022 走看看