SPOJ694&&SPOJ705:Distinct Substrings(后缀数组)

来源:互联网 发布:常用的音频编辑软件 编辑:程序博客网 时间:2024/06/06 18:34

Description

Given a string, we need to find the total number of its distinct substrings.

Input

T- number of test cases. T<=20;
Each test case consists of one string, whose length is <= 1000

Output

For each test case output one number saying the number of distinct substrings.

Example

Sample Input:
2
CCCCC
ABABA

Sample Output:
5
9

Explanation for the testcase with string ABABA: 
len=1 : A,B
len=2 : AB,BA
len=3 : ABA,BAB
len=4 : ABAB,BABA
len=5 : ABABA
Thus, total number of distinct substrings is 9.

Hint


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

一看到这道题,直觉就告诉我肯定是所有子串的数量减去所有height数组里的数值和,然后试着写了下就AC了,然后再仔细想了下,也确实如此,因为这些公共前缀都是多加了的


#include <iostream>#include <stdio.h>#include <string.h>#include <stack>#include <queue>#include <map>#include <set>#include <vector>#include <math.h>#include <bitset>#include <algorithm>#include <climits>using namespace std;#define LS 2*i#define RS 2*i+1#define UP(i,x,y) for(i=x;i<=y;i++)#define DOWN(i,x,y) for(i=x;i>=y;i--)#define MEM(a,x) memset(a,x,sizeof(a))#define W(a) while(a)#define gcd(a,b) __gcd(a,b)#define LL long long#define N 1005#define MOD 1000000007#define INF 0x3f3f3f3f#define EXP 1e-8int wa[N],wb[N],wsf[N],wv[N],sa[N];int rank[N],height[N],s[N],a[N];char str[N],str1[N],str2[N];//sa:字典序中排第i位的起始位置在str中第sa[i]//rank:就是str第i个位置的后缀是在字典序排第几//height:字典序排i和i-1的后缀的最长公共前缀int cmp(int *r,int a,int b,int k){    return r[a]==r[b]&&r[a+k]==r[b+k];}void getsa(int *r,int *sa,int n,int m)//n要包含末尾添加的0{    int i,j,p,*x=wa,*y=wb,*t;    for(i=0; i<m; i++)  wsf[i]=0;    for(i=0; i<n; i++)  wsf[x[i]=r[i]]++;    for(i=1; i<m; i++)  wsf[i]+=wsf[i-1];    for(i=n-1; i>=0; i--)  sa[--wsf[x[i]]]=i;    p=1;    j=1;    for(; p<n; j*=2,m=p)    {        for(p=0,i=n-j; i<n; i++)  y[p++]=i;        for(i=0; i<n; i++)  if(sa[i]>=j)  y[p++]=sa[i]-j;        for(i=0; i<n; i++)  wv[i]=x[y[i]];        for(i=0; i<m; i++)  wsf[i]=0;        for(i=0; i<n; i++)  wsf[wv[i]]++;        for(i=1; i<m; i++)  wsf[i]+=wsf[i-1];        for(i=n-1; i>=0; i--)  sa[--wsf[wv[i]]]=y[i];        t=x;        x=y;        y=t;        x[sa[0]]=0;        for(p=1,i=1; i<n; i++)            x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++;    }}void getheight(int *r,int n)//n不保存最后的0{    int i,j,k=0;    for(i=1; i<=n; i++)  rank[sa[i]]=i;    for(i=0; i<n; i++)    {        if(k)            k--;        else            k=0;        j=sa[rank[i]-1];        while(r[i+k]==r[j+k])            k++;        height[rank[i]]=k;    }}int t,ans,n,m;int main(){    int i,j,k,len;    scanf("%d",&t);    W(t--)    {        scanf("%s",str);        len = strlen(str);        UP(i,0,len-1)        s[i]=str[i];        s[len] = 0;        getsa(s,sa,len+1,300);        getheight(s,len);        ans = (1+len)*len/2;        UP(i,2,len)        ans-=height[i];        printf("%d\n",ans);    }}


0 0
原创粉丝点击