后缀数组:SPOJ SUBST1 - New 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 <= 50000

Output

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

Example

Input:
2
CCCCC
ABABA

Output:
5
9

  题意:求一个字符串有多少不同子串
  LCP的应用,会打后缀数组的模板后就十分简单了
  后缀数组的理解:
  http://www.cnblogs.com/staginner/archive/2012/02/02/2335600.html
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 
 7 const int maxn=50010;
 8 char S[maxn];
 9 
10 int r[maxn],wa[maxn],wb[maxn],ws[maxn],wv[maxn],sa[maxn];
11 
12 bool cmp(int *p,int a,int b,int l)
13 {return p[a]==p[b]&&p[a+l]==p[b+l];}
14 
15 void DA(int n,int m)
16 {
17     int i,j,p,*x=wa,*y=wb,*t;
18     for(int i=0;i<m;i++)
19         ws[i]=0;
20     for(int i=0;i<n;i++)
21         ++ws[x[i]=r[i]];
22     for(int i=1;i<m;i++)
23         ws[i]+=ws[i-1];
24     for(int i=n-1;i>=0;i--)
25         sa[--ws[x[i]]]=i;
26         
27     for(j=1,p=1;p<n;j*=2,m=p)
28     {
29         for(p=0,i=n-j;i<n;i++)
30             y[p++]=i;
31         for(i=0;i<n;i++)
32             if(sa[i]>=j)
33                 y[p++]=sa[i]-j;    
34         for(i=0;i<n;i++)
35             wv[i]=x[y[i]];    
36         for(i=0;i<m;i++)
37             ws[i]=0;
38         for(i=0;i<n;i++)
39             ++ws[wv[i]];
40         for(i=1;i<m;i++)
41             ws[i]+=ws[i-1];
42         for(i=n-1;i>=0;i--)
43             sa[--ws[wv[i]]]=y[i];
44         for(t=x,x=y,y=t,x[sa[0]]=0,p=1,i=1;i<n;i++)
45             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
46                      
47     }            
48 } 
49 int lcp[maxn],rank[maxn];
50 void Lcp(int n)
51 {
52     int i,j,k=0;
53     for(i=1;i<=n;i++)
54         rank[sa[i]]=i;
55     for(i=0;i<n;lcp[rank[i++]]=k)
56         for(k?--k:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);    
57 }
58 
59 int main()
60 {
61     int Q,n;
62     scanf("%d",&Q);
63     while(Q--)
64     {
65         scanf("%s",S);
66         int i;
67         for(i=0;S[i];i++)r[i]=S[i];
68         n=i;
69         DA(n+1,128);
70         Lcp(n);
71         long long ans=0;
72         for(int i=0;i<n;i++)
73             ans+=n-i-lcp[rank[i]];
74         printf("%lld\n",ans);    
75     } 
76     
77     return 0;
78 }

 


 

 

你可能感兴趣的:(后缀数组:SPOJ SUBST1 - New Distinct Substrings)