zoukankan      html  css  js  c++  java
  • SPOJ 694 DISUBSTR

    思路

    求本质不同的子串个数,总共重叠的子串个数就是height数组的和
    总子串个数-height数组的和即可

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define int long long
    const int MAXN = 100000;
    using namespace std;
    int height[MAXN],sa[MAXN],ranks[MAXN],barrel[MAXN],n;
    struct Node{
        int pos,r[2]; 
    }midx[MAXN],x[MAXN];
    char s[MAXN];
    int c_sort(int n,int lim){
        for(int i=0;i<2;i++){   
            memset(barrel,0,sizeof(barrel));    
            for(int j=1;j<=n;j++)
                barrel[x[j].r[i]]++;
            for(int j=1;j<=lim;j++)
                barrel[j]+=barrel[j-1];
            for(int j=n;j>=1;j--)
                midx[barrel[x[j].r[i]]--]=x[j];
            for(int j=1;j<=n;j++)
                x[j]=midx[j];
        }
        ranks[x[1].pos]=1;
        int cnt=1;
        for(int i=2;i<=n;i++){
            if(x[i].r[0]==x[i-1].r[0]&&x[i].r[1]==x[i-1].r[1])
                ranks[x[i].pos]=cnt;
            else
                ranks[x[i].pos]=++cnt;
        }
        return cnt;
    }
    void cal_sa(int n){
        for(int i=1;i<=n;i++)
            x[i]=(Node){i,s[i],0};
        int cnt=c_sort(n,1500);
        for(int i=1;cnt<n;i<<=1){
            for(int j=1;j<=n;j++)
                x[j]=(Node){j,(i+j<=n)?ranks[i+j]:0,ranks[j]};
            cnt=c_sort(n,cnt);
        }
        for(int i=1;i<=n;i++)
            sa[ranks[i]]=i;
        for(int i=1,j=0,k;i<=n;height[ranks[i++]]=j)
            for(j?j--:0,k=sa[ranks[i]-1];s[i+j]==s[j+k];j++);
    }
    void init(void){
       memset(sa,0,sizeof(sa));
       memset(height,0,sizeof(height));
       memset(ranks,0,sizeof(ranks));
       memset(x,0,sizeof(x));
       memset(midx,0,sizeof(midx));
    }
    signed main(){
        int T;
        scanf("%lld",&T);
        while(T--){
            init();
            scanf("%s",s+1);
            n=strlen(s+1);  
            cal_sa(n);
            int sum=0;
            for(int i=2;i<=n;i++)
                sum+=height[i];
            printf("%lld
    ",(n+1)*n/2-sum);
        }
        return 0;
    }
    
  • 相关阅读:
    find命令
    shell编程基础
    grep命令
    awk命令
    结对项目之需求分析与原型模型设计
    使用Git进行代码管理的心得
    软件工程的实践项目的自我目标
    第五次作业——团队项目——需求规格说明书
    调研android开发环境的发展演变
    结对编程总结
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10476549.html
Copyright © 2011-2022 走看看