Enumerates the length of a substring, grouped by height, if the difference between the SA minimum and SA maximum is greater than the length of the enumeration, this group contributes 1 to the answer.
1#include <iostream>2#include <vector>3#include <algorithm>4#include <string>5#include <string.h>6#include <stdio.h>7#include <queue>8#include <stack>9#include <map>Ten#include <Set> One#include <cmath> A#include <ctime> -#include <cassert> -#include <sstream> the using namespacestd; - - Const intn=223456; - Const intmod=1e9+7; + - + CharS[n]; A structSuffixarray {; at intSa[n]; - intT1[n],t2[n],c[n]; - intRk[n],height[n]; - -Inlineintcmpint*r,intAintBintl) { - returnr[a]==r[b]&&r[a+l]==r[b+l]; in } - voidCALCSA (Char*s,intNintm) { to inti,j,p,*x=t1,*y=T2; + for(i=0; i<m;i++) c[i]=0; - for(i=0; i<n;i++) c[x[i]=s[i]]++; the for(i=1; i<m;i++) c[i]+=c[i-1]; * for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i; $ for(j=1; j<=n;j<<=1){Panax Notoginsengp=0; - for(i=n-j;i<n;i++) y[p++]=i; the for(i=0; i<n;i++)if(sa[i]>=j) Y[p++]=sa[i]-j;//rank from small to large, if POS is larger than J, then the second keyword of suffix (sa[i]-j) is P + for(i=0; i<m;i++) c[i]=0; A for(i=0; i<n;i++) c[x[y[i]]]++; the for(i=1; i<m;i++) c[i]+=c[i-1]; + for(i=n-1; i>=0; i--) Sa[--c[x[y[i]]]]=y[i];//depending on the second keyword from large to small, determine the new round of SA - swap (x, y); $p=1; x[sa[0]]=0; $ for(i=1; i<n;i++) -X[SA[I]]=CMP (y,sa[i-1],sa[i],j)? p1:p + +; - if(p>=n) Break; them=p; - }Wuyi } the voidCalcheight (Char*s,intN) { - inti,j,k=0; Wu for(i=0; i<=n;i++) rk[sa[i]]=i; - for(i=0; i<n;i++){ About if(k) k--;//h[i]>=h[i-1]-1 $j=sa[rk[i]-1];//suffix (j) was ranked before suffix (i) - while(S[i+k]==s[j+k]) k++;//Violent calculation LCP -height[rk[i]]=K; - } A } + intLcpintAintBintLen) { the if(a==b)returnlen-A; - intra=rk[a],rb=Rk[b]; $ if(ra>RB) Swap (RA,RB); the returnQueryst (ra+1, RB); the } the the intst[n][ -];//The second dimension is guaranteed to be greater than log (n<<1) - voidINITST (intN) { in for(intI=1; i<=n; i++) thest[i][0]=Height[i]; the for(intj=1; (1<<J) <=n; J + +) { About intk=1<< (J-1); the for(intI=1; i+k<=n; i++) theSt[i][j]=min (st[i][j-1],st[i+k][j-1]); the } + } - intQueryst (intAintb) { the if(a>b) Swap ( A, a);Bayi intdis=b-a+1; the intK=log ((Double) dis)/log (2.0); the returnMin (st[a][k],st[b-(1<<K) +1][k]); - } - }suf; the the intMain () { the while(SCANF ("%s", s)! =EOF) { the if(s[0]=='#') Break; - intn=strlen (s); theSUF.CALCSA (s,n+1, -); the suf.calcheight (s,n); the //for (int i=0;i<=n;i++) cout<<suf.sa[i]<< "";cout<<endl;94 //for (int i=0;i<=n;i++) cout<<suf.height[i]<< "";cout<<endl; the intret=0; the for(intI=1; i<=n/2; i++) { the intmi=suf.sa[1],ma=suf.sa[1];98 for(intj=2; j<=n;j++) { About if(suf.height[j]<i) { - if(MI+I<=MA) ret++;101Mi=Suf.sa[j];102Ma=Suf.sa[j];103 104 } theMi=min (mi,suf.sa[j]);106Ma=Max (ma,suf.sa[j]);107 }108 if(MI+I<=MA) ret++;109 } thecout<<ret<<Endl;111 } the return 0;113}
View Code
HDU3518 suffix array to find the number of different substrings that cannot overlap and recur