Title Link: Https://vjudge.net/contest/70655#problem/C
Another magical application of the suffix array. The number of different substrings is actually the number of different prefixes for all suffixes.
Considering that all suffixes are ranked by rank, we now know the height, which is the longest common prefix of two adjacent. So how do you count the number of different substrings?
Starting from the first string, consider Ans+=l1. Look at the second string, which will add a few different prefixes? Is ans+=l2-height[2]. A third similar, will add in ans+=l3-height[3] ...
So the final result is ans=l* (l+1)/2-sigma (HEIGHT[2..N]). L is the length of the entire string.
But look at the data range of the problem can be hashed, but this problem is not: Https://vjudge.net/contest/70655#problem/D, and this problem will explode long long ...
#include <cstdio>#include<algorithm>#include<cstring>#include<queue>using namespacestd;Const intmaxn=1005;#defineF (x) ((x)/3+ ((x)%3==1?0:TB))#defineG (x) ((x) <TB? ( x) *3+1: (((x)-TB) *3+2)intwa[maxn*3],wb[maxn*3],wv[maxn*3],wss[maxn*3];intC0 (int*r,intAintb) { returnR[A]==R[B] && r[a+1]==r[b+1] && r[a+2]==r[b+2];}intC12 (intKint*r,intAintb) { if(k==2)returnR[A]<R[B] | | (R[A]==R[B]&&C12 (1, r,a+1, B +1)); Else returnR[A]<R[B] | | (r[a]==r[b]&&wv[a+1]<wv[b+1]);}voidSortint*r,int*a,int*b,intNintm) { inti; for(i=0; i<n;i++) wv[i]=R[a[i]]; for(i=0; i<m;i++) wss[i]=0; for(i=0; i<n;i++) wss[wv[i]]++; for(i=1; i<m;i++) wss[i]+=wss[i-1]; for(i=n-1; i>=0; i--) b[--wss[wv[i]]]=a[i];}voidDC3 (int*r,int*sa,intNintm) { inti,j,*rn=r+N; int*san=sa+n,ta=0, tb= (n+1)/3, tbc=0, p; R[n]=r[n+1]=0; for(i=0; i<n;i++)if(i%3!=0) wa[tbc++]=i; Sort (R+2, wa,wb,tbc,m); Sort (R+1, wb,wa,tbc,m); Sort (r,wa,wb,tbc,m); for(p=1, Rn[f (wb[0])]=0, i=1; i<tbc;i++) rn[f (Wb[i])=C0 (r,wb[i-1],wb[i])? p1:p + +; if(p<tbc) DC3 (rn,san,tbc,p); Else for(i=0; i<tbc;i++) san[rn[i]]=i; for(i=0; i<tbc;i++)if(SAN[I]<TB) wb[ta++]=san[i]*3; if(n%3==1) wb[ta++]=n-1; Sort (r,wb,wa,ta,m); for(i=0; i<tbc;i++) wv[wb[i]=g (San[i])]=i; for(i=0, j=0, p=0; i<ta&&j<tbc;p++) Sa[p]=C12 (wb[j]%3, R,wa[i],wb[j])? wa[i++]:wb[j++]; for(; i<ta;p++) sa[p]=wa[i++]; for(; j<tbc;p++) sa[p]=wb[j++];}voidDaintStr[],intSa[],intRank[],intHeight[],intNintm) { for(inti=n;i<n*3; i++) Str[i]=0; DC3 (Str,sa,n+1, M); inti,j,k=0; for(i=0; i<=n;i++) rank[sa[i]]=i; for(i=0; i<n;i++) { if(k) k--; J=sa[rank[i]-1]; while(Str[i+k]==str[j+k]) k++; Height[rank[i]]=K; }}CharS[MAXN];inta[maxn*3];intra[maxn*3],height[maxn*3],sa[maxn*3];intSolveintN) { //HEIGHT[2..N] intans=n* (n+1)/2; for(intI=2; i<=n;i++) ans-=Height[i]; returnans;}intMain () {intT; scanf ("%d",&t); while(t--) {scanf ("%s", s); intL=strlen (s); for(intI=0; i<l;i++) a[i]= (int) s[i]; Da (a,sa,ra,height,l, +); printf ("%d\n", Solve (l)); } return 0;}
[Spoj disubstr] Suffix array count the number of different substrings