SPOJ Problem Set (classical)694. Distinct SubstringsProblem code: DISUBSTR |
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 <= 1000
For each test case output one number saying the number of distinct substrings.
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.
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <queue> #include <algorithm> #include <map> #include <iomanip> #define INF 99999999 typedef long long LL; using namespace std; const int MAX=1000+10; int *rank,r[MAX],sa[MAX],height[MAX]; int wa[MAX],wb[MAX],wm[MAX]; char s[MAX]; bool cmp(int *r,int a,int b,int l){ return r[a] == r[b] && r[a+l] == r[b+l]; } void makesa(int *r,int *sa,int n,int m){ int *x=wa,*y=wb,*t; for(int i=0;i<m;++i)wm[i]=0; for(int i=0;i<n;++i)wm[x[i]=r[i]]++; for(int i=1;i<m;++i)wm[i]+=wm[i-1]; for(int i=n-1;i>=0;--i)sa[--wm[x[i]]]=i; for(int i=0,j=1,p=0;p<n;j=j*2,m=p){ for(p=0,i=n-j;i<n;++i)y[p++]=i; for(i=0;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j; for(i=0;i<m;++i)wm[i]=0; for(i=0;i<n;++i)wm[x[y[i]]]++; for(i=1;i<m;++i)wm[i]+=wm[i-1]; for(i=n-1;i>=0;--i)sa[--wm[x[y[i]]]]=y[i]; for(t=x,x=y,y=t,i=p=1,x[sa[0]]=0;i<n;++i){ x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p-1:p++; } } rank=x; } void calheight(int *r,int *sa,int n){ for(int i=0,j=0,k=0;i<n;height[rank[i++]]=k){ for(k?--k:0,j=sa[rank[i]-1];r[i+k] == r[j+k];++k); } } int main(){ int t; cin>>t; while(t--){ cin>>s; int len=0; for(len=0;s[len] != '\0';++len)r[len]=s[len]; r[len]=0; makesa(r,sa,len+1,256); calheight(r,sa,len+1); int sum=0; for(int i=1;i<=len;++i){ sum+=len-sa[i]-height[i]; } cout<<sum<<endl; } return 0; }