Given a string, we need to find the total number of its distinct substrings.
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000
For each test case output one number saying the number of distinct substrings.
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
原文:http://www.cnblogs.com/TenderRun/p/5193869.html