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 const int maxn=50010; 7 char S[maxn]; 8 int r[maxn],wa[maxn],wb[maxn],wv[maxn],ws[maxn],sa[maxn]; 9 10 bool cmp(int *p,int i,int j,int l) 11 {return p[i]==p[j]&&p[i+l]==p[j+l];} 12 13 void DA(int n,int m) 14 { 15 int i,j,p,*x=wa,*y=wb,*t; 16 for(i=0;i<m;i++) 17 ws[i]=0; 18 for(i=0;i<n;i++) 19 ++ws[x[i]=r[i]]; 20 for(i=1;i<m;i++) 21 ws[i]+=ws[i-1]; 22 for(i=n-1;i>=0;i--) 23 sa[--ws[x[i]]]=i; 24 25 for(j=1,p=1;p<n;j<<=1,m=p) 26 { 27 for(p=0,i=n-j;i<n;i++) 28 y[p++]=i; 29 for(i=0;i<n;i++) 30 if(sa[i]>=j) 31 y[p++]=sa[i]-j; 32 for(i=0;i<n;i++) 33 wv[i]=x[y[i]]; 34 for(i=0;i<m;i++) 35 ws[i]=0; 36 for(i=0;i<n;i++) 37 ++ws[wv[i]]; 38 for(i=1;i<m;i++) 39 ws[i]+=ws[i-1]; 40 for(i=n-1;i>=0;i--) 41 sa[--ws[wv[i]]]=y[i]; 42 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 43 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 44 } 45 } 46 47 int rank[maxn],lcp[maxn]; 48 void LCP(int n) 49 { 50 int i,j,k=0; 51 for(i=1;i<=n;i++) 52 rank[sa[i]]=i; 53 for(i=0;i<n;lcp[rank[i++]]=k) 54 for(k?k--:k,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); 55 } 56 57 int main() 58 { 59 int Q; 60 scanf("%d",&Q); 61 while(~scanf("%s",S)) 62 { 63 int i,n; 64 long long ans=0; 65 for(i=0;S[i];i++) 66 r[i]=S[i]; 67 DA(i+1,128); 68 LCP(i); 69 n=i; 70 for(i=0;i<n;i++) 71 ans+=n-i-lcp[rank[i]]; 72 printf("%d ",ans); 73 } 74 return 0; 75 }