SPOJ Distanct Substrings(求不同子串的数量)
Posted songorz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ Distanct 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.
题解:题意就是让你求子串的种类;
思路:后缀数组,然后每个字符的贡献为n-sa[i]-height[i];(n为字符的个数);
参考代码:
1 //#include<bits/stdc++.h> 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<string> 6 #include<cstdlib> 7 #include<cmath> 8 #include<algorithm> 9 using namespace std; 10 #define clr(a,val) memset(a,val,sizeof(a)) 11 #define lowbit(x) x&-x 12 #define eps 1e-6 13 typedef long long ll; 14 const int INF=0x3f3f3f3f; 15 const int maxn=1010; 16 struct SuffixArray{ 17 int s[maxn]; 18 int sa[maxn],height[maxn],rank[maxn],n; 19 int t[maxn*2],t2[maxn*2]; 20 int cnt[maxn]; 21 void build_sa(int m)//字符都属于0~m-1范围 22 { 23 int i,*x=t,*y=t2; 24 for(i=0;i<m;i++) cnt[i]=0; 25 for(i=0;i<n;i++) cnt[x[i]=s[i]]++; 26 for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; 27 for(i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i; 28 for(int k=1,p;k<=n;k <<=1)//k<=n 29 { 30 p=0; 31 for(i=n-k;i<n;i++) y[p++]=i; 32 for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; 33 for(i=0;i<m;i++) cnt[i]=0; 34 for(i=0;i<n;i++) cnt[x[y[i]]]++; 35 for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; 36 for(i=n-1;i>=0;i--) sa[--cnt[x[y[i]]]]=y[i]; 37 swap(x,y); 38 p=1;x[sa[0]]=0; 39 for(i=1;i<n;i++) 40 x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]? p-1:p++; 41 if(p>=n) break; 42 m=p; 43 } 44 } 45 void build_height() 46 { 47 int k=0; 48 for(int i=0;i<n;i++) rank[sa[i]]=i; 49 for(int i=0;i<n-1;i++) 50 { 51 if(k) k--; 52 int j=sa[rank[i]-1]; 53 while(s[i+k]==s[j+k]) k++; 54 height[rank[i]]=k; 55 } 56 } 57 } SA; 58 int main() 59 { 60 int n, m, t; 61 string str; 62 cin>>t; 63 while(t--) 64 { 65 cin>>str; 66 int n = str.size(); 67 for(int i = 0; i<n; i++) SA.s[i] = str[i]; 68 SA.s[n] = 0;SA.n=n+1; 69 SA.build_sa(128); 70 SA.build_height(); 71 int ans = 0; 72 for(int i=1;i<=n;i++) ans+=n-SA.sa[i]-SA.height[i]; 73 cout<<ans<<endl; 74 } 75 return 0; 76 }
以上是关于SPOJ Distanct Substrings(求不同子串的数量)的主要内容,如果未能解决你的问题,请参考以下文章
Spoj-DISUBSTR - Distinct Substrings~New Distinct Substrings SPOJ - SUBST1~(后缀数组求解子串个数)