spoj 694 Distinct Substrings

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.

 

题目大意: 给你一个字符串,问互补相同的字串有几个。 

我们知道每一个字串都是后缀的前缀,所以我们只要先求出后缀数组,然后对于排名相邻的两个串,比如排名为第i的串,他提供的前缀数量是len-sa[i],但由于有H[i]个和排名第i-1的是一样的,所以我们要减去h[i],这样扫一遍就可以了。  

 1 #include<bits/stdc++.h>
 2 using namespace std; 
 3 int const N=1000+3;  
 4 int wa[N<<1],wb[N<<1],wv[N],rk[N],h[N],num[N],sa[N];    
 5 char s[N]; 
 6 int cmp(int *r,int x,int y,int z){
 7     return r[x]==r[y] && r[x+z]==r[y+z];  
 8 } 
 9 void build_sa(char *r,int *sa,int n,int m){
10   int i,j,p,*x=wa,*y=wb;  
11   for(i=0;i<m;i++) num[i]=0;  
12   for(i=0;i<n;i++) num[x[i]=r[i]]++;  
13   for(i=1;i<m;i++) num[i]+=num[i-1];  
14   for(i=n-1;i>=0;i--) sa[--num[x[i]]]=i; 
15   for(j=1,p=1;p<n;m=p){
16     for(p=0,i=n-j;i<n;i++) y[p++]=i;  
17     for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 
18     for(i=0;i<m;i++) num[i]=0; 
19     for(i=0;i<n;i++) num[wv[i]=x[y[i]]]++;  
20     for(i=1;i<m;i++) num[i]+=num[i-1];  
21     for(i=n-1;i>=0;i--) sa[--num[wv[i]]]=y[i]; 
22     swap(x,y); 
23     for(i=1,p=1,x[sa[0]]=0;i<n;i++) 
24       x[sa[i]]=cmp(y,sa[i],sa[i-1],j)? p-1:p++; 
25   }
26   for(i=0;i<n;i++) rk[i]=x[i]; 
27 }
28 void build_h(char *r,int *sa,int n){    
29     int k=0; 
30     for(int i=0;i<n;i++){
31         if(k) k--; 
32         int j=sa[rk[i]-1];  
33         while (r[i+k]==r[j+k]) k++; 
34         h[rk[i]]=k;
35     }
36 }  
37 void solve(int n){
38     int ans=0; 
39     for(int i=1;i<=n;i++){
40         int num=n-sa[i]; 
41          ans+=num-h[i];  
42     } 
43     printf("%d\n",ans); 
44 }   
45 int main(){
46   int cas;   
47   scanf("%d",&cas);  
48   while (cas--){
49     scanf("%s",s);  
50     int len=strlen(s);  
51     build_sa(s,sa,len+1,130);   
52     build_h(s,sa,len); 
53     solve(len);  
54   }
55   return 0; 
56 }  
View Code

 

posted @ 2019-06-10 16:19  zjxxcn  阅读(184)  评论(0编辑  收藏  举报