To find the number of different substrings the problem is equivalent to the number of prefixes that are not equal to all suffixes. That is, for each suffix suffix (sa[i]), will contribute n-sa[i]+1, but at the same time, to subtract those duplicates, that is, height[i], the answer is n-sa[i]+1-height[i] cumulative.
Constmaxn=1419;varX,y,rank,sa,h,c:Array[0.. MAXN] oflongint; s:ansistring; t,q,n:longint ;functionMax (x,y:longint): Longint;begin ifX>y ThenExit (x)ElseExit (y);End;functionMin (x,y:longint): Longint;begin ifX<y ThenExit (x)ElseExit (y);End;procedureMake ;varI,j,p,tot:longint;beginP:=1; whileP<n Do beginFillchar (C,sizeof (c),0); fori:=1 toN-p Doy[i]:=rank[i+p]; fori:= n-p+1 toN Doy[i]:=0; fori:=1 toN DoInc (C[y[i]); fori:=1 toN DoInc (c[i],c[i-1]); fori:=1 toN Do beginSa[c[y[i]]:=i; Dec (C[y[i]]); End; Fillchar (C,sizeof (c),0); fori:=1 toN Dox[i]:=Rank[i]; fori:=1 toN DoInc (C[x[i]); fori:=1 toN DoInc (c[i],c[i-1]); fori:= NDownto 1 Do beginY[sa[i]]:=C[x[sa[i]]; Dec (C[x[sa[i]]); End; fori:=1 toN Dosa[y[i]]:=i; Tot:=1; rank[sa[1]]:=1; fori:=2 toN Do begin if(x[sa[i]]<>x[sa[i-1]])or(x[sa[i]+p]<>x[sa[i-1]+P]) ThenInc (TOT); Rank[sa[i]]:=tot; End; P:=p<<1; End;End;proceduremakeht;varI,j,p:longint;beginh[1]:=0; p:=0; fori:=1 toN Do beginP:=max (P-1,0); ifrank[i]=1 Thencontinue; J:=sa[rank[i]-1]; while(i+p<=n) and(j+p<=n) and(S[i+p]=s[j+p]) DoInc (P); H[rank[i]]:=p; End;End;procedureInit;vari,j,tot:longint; ch:char;beginReadln (s); N:=length (s); fori:=1 toN Dox[i]:=Ord (s[i]); Fillchar (C,sizeof (c),0); fori:=1 toN DoInc (C[x[i]); fori:=1 to the DoInc (c[i],c[i-1]); fori:=1 toN Do beginSa[c[x[i]]:=i; Dec (C[x[i]]); End; rank[sa[1]]:=1; tot:=1; fori:=2 toN Do begin ifx[sa[i]]<>x[sa[i-1]] ThenInc (TOT); Rank[sa[i]]:=tot; End; make ; makeht;End;proceduresolve;varAns,i:longint;beginans:=0; fori:=1 toN DoInc (ans,n-sa[i]+1-H[i]); Writeln (ans);End; Begin readln (t); forq:=1 toT Do beginInit; Solve End; End.
"SPOJ694" Distinct substrings (SA)