Distinct Substrings(spoj 694)

Posted Cola

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Distinct Substrings(spoj 694)相关的知识,希望对你有一定的参考价值。

题意:要求不同子串的个数

/*
    先求出height数组,不难看出height之和就是重复的字符串个数,用总的减去它就行了。 
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 100010
int sa[N],rk[N],height[N],t1[N],t2[N],c[N];
char s[N];
using namespace std;
bool cmp(int *y,int a,int b,int k){
    return y[a]==y[b]&&y[a+k]==y[b+k];
}
void DA(int n,int m){
    int *x=t1,*y=t2;
    for(int i=0;i<m;i++) c[i]=0;
    for(int i=0;i<n;i++) c[x[i]=s[i]]++;
    for(int i=1;i<m;i++) c[i]+=c[i-1];
    for(int i=n-1;~i;i--) sa[--c[x[i]]]=i;
    for(int k=1,p=0;k<=n;k*=2,m=p,p=0){
        for(int i=n-k;i<n;i++) y[p++]=i;
        for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
        for(int i=0;i<m;i++) c[i]=0;
        for(int i=0;i<n;i++) c[x[y[i]]]++;
        for(int i=1;i<m;i++) c[i]+=c[i-1];
        for(int i=n-1;~i;i--) sa[--c[x[y[i]]]]=y[i];
        swap(x,y);p=1;x[sa[0]]=0;
        for(int i=1;i<n;i++)
            if(cmp(y,sa[i-1],sa[i],k)) x[sa[i]]=p-1;
            else x[sa[i]]=p++;
        if(p>=n) break;
    }
    for(int i=0;i<n;i++) rk[sa[i]]=i;
}
void get_ht(int n){
    for(int i=0,j,k=0;i<n;height[rk[i++]]=k){
        j=sa[rk[i]-1];k=k?k-1:0;
        while(s[i+k]==s[j+k]) k++;
    }
}
int solve(int n){
    long long sum=1LL*n*(n+1)/2;
    for(int i=1;i<=n;i++) sum-=(long long)height[i];
    return (int)sum;
}
int main(){
    int T;scanf("%d",&T);
    while(T--){
        scanf("%s",s);int n=strlen(s);
        DA(n+1,128);
        get_ht(n);
        printf("%d\n",solve(n));
    }
    return 0;
}

 

以上是关于Distinct Substrings(spoj 694)的主要内容,如果未能解决你的问题,请参考以下文章

SPOJ694/DISUBSTR???Distinct Substrings????????????

Distinct Substrings(spoj 694)

SPOJ - DISUBSTR Distinct Substrings

spoj694 DISUBSTR - Distinct Substrings

SPOJ 705 Distinct Substrings(后缀数组)

SPOJ705-New Distinct Substrings-后缀数组