• SPOJ_705_New Distinct Substrings_后缀数组


    SPOJ_705_New Distinct Substrings_后缀数组

    题意:

    给定一个字符串,求该字符串含有的本质不同的子串数量。


    后缀数组的一个小应用。

    考虑每个后缀的贡献,如果不要求本质不同那就是n-sa[i]-1。

    然后需要去重,就是把height[i]这部分减掉。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <stdlib.h>
    using namespace std;
    #define N 50050
    int ws[N],wa[N],wb[N],wv[N],r[N],sa[N],height[N],rank[N],n,m;
    char s[N];
    void build_suffix_array() {
        m=129;
        int i,j,p,*x=wa,*y=wb,*t;
        for(i=0;i<m;i++) ws[i]=0;
        for(i=0;i<n;i++) ws[x[i]=r[i]]++;
        for(i=1;i<m;i++) ws[i]+=ws[i-1];
        for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
        for(j=p=1;p<n;j<<=1,m=p) {
            for(p=0,i=n-j;i<n;i++) y[p++]=i;
            for(i=0;i<n;i++) if(sa[i]-j>=0) y[p++]=sa[i]-j;
            for(i=0;i<n;i++) wv[i]=x[y[i]];
            for(i=0;i<m;i++) ws[i]=0;
            for(i=0;i<n;i++) ws[wv[i]]++;
            for(i=1;i<m;i++) ws[i]+=ws[i-1];
            for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
            for(t=x,x=y,y=t,x[sa[0]]=0,i=p=1;i<n;i++) {
                if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+j]==y[sa[i-1]+j]) x[sa[i]]=p-1;
                else x[sa[i]]=p++;
            }
        }
        for(i=1;i<n;i++) rank[sa[i]]=i;
        for(i=p=0;i<n-1;height[rank[i++]]=p) 
            for(p?p--:0,j=sa[rank[i]-1];r[i+p]==r[j+p];p++) ;
    }
    int main() {
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%s",s);
            int i;
            n=strlen(s);
            for(i=0;i<n;i++) r[i]=s[i];
            r[n++]=0;
            build_suffix_array();
            long long ans=0;
            for(i=1;i<n;i++) ans+=n-sa[i]-1-height[i];
            printf("%lld
    ",ans); 
        }
    }
    
  • 相关阅读:
    文件上传
    使用servlet+jdbc+MD5实现用户加密登录
    JDBC入门
    springmvc(三)
    springmvc(二)
    springmvc(一)
    JavaScript总结(一)
    Spring的AOP面向切面编程
    Spring框架(三)
    Spring框架(二)
  • 原文地址:https://www.cnblogs.com/suika/p/9203852.html
Copyright © 2020-2023  润新知