http://acm.hdu.edu.cn/showproblem.php?pid=5769
Test instructions: Find out the number of different substrings that appear in the X string in the s string? of which 1 <= | s| < $10^5$
The official puzzle: processing sa[] arrays and height[] arrays in the suffix array. Without considering the inclusion of the character X, the number of different substrings is
If the character x is required, simply record the position (in Nxt[sa[i]) of the nearest character x of the distance sa[i], the number
Understanding: The suffix array height[i] is the LCP of sa[i] and sa[i-1], solving all the different substrings in the suffix array (previously only the SAM handles all the different substrings). It is better to understand, when it is necessary to have a substring x, you need to KMP find all the matching position, in the processing to the suffix of I, take Max can be said to contain X, and is a different substring;
#pragmaComment (linker, "/stack:1024000000,1024000000")#include<bits/stdc++.h>using namespacestd;#defineRep0 (I,L,R) for (int i = (l); i < (R); i++)#defineREP1 (I,L,R) for (int i = (l); I <= (r); i++)#defineRep_0 (i,r,l) for (int i = (r); i > (l); i--)#defineRep_1 (i,r,l) for (int i = (r); I >= (l); i--)#defineMS0 (a) memset (A,0,sizeof (a))#defineMS1 (a) memset (A,-1,sizeof (a))#defineMSi (a) memset (A,0x3f,sizeof (a))#defineINF 0x3f3f3f3f#definePB Push_back#defineMK Make_pair#defineA First#defineB Second#defineEPS 1e-8#defineZero (x) (((x) >0? ( x):-(x)) <eps)#defineBitnum (a) __builtin_popcount (a)#defineLowbit (x) (x& (×))#defineCLEAR0 (0xFFFFFFFE)#defineMoD 1000000007#defineK (x) ((x) * (x))typedef pair<int,int>Pii;typedefLong Longll;typedef unsignedLong Longull;template<typename t>voidRead1 (T &m) {T x=0, F =1;CharCH =GetChar (); while(Ch <'0'|| CH >'9'){if(ch = ='-') F =-1; ch=GetChar ();} while(Ch >='0'&& CH <='9') {x = x*Ten+ CH-'0'; ch =GetChar ();} M= x*F;} Template<typename t>voidRead2 (T &a,t &b) {Read1 (a); Read1 (b);} Template<typename t>voidRead3 (T &a,t &b,t &c) {Read1 (a); Read1 (b); Read1 (c);} Template<typename t>void out(T a) {if(a>9) out(ATen); Putchar (A%Ten+'0');} inline ll gcd (ll A,ll b) {returnb = =0? A:GCD (b,a%b); }template<classT1,classT2> InlinevoidGmax (t1& A, T2 b) {if(A < b) A =b;} Template<classT1,classT2> InlinevoidGmin (t1& A, T2 b) {if(A > B) a =b;}Const intMAXN =100001;intSA[MAXN], T[MAXN],T2[MAXN],C[MAXN],W[MAXN];intcmpint*r,intAintBintl) { returnR[a] = = R[b] && r[a+l] = = r[b+l];}voidBuild_sa (Char*r,intNintm) { intI, J, p, *x = t, *y =T2; for(i =0; I < m;i++) C[i] =0; for(i =0; I < n;i++) C[x[i] = r[i]]++; for(i =1; I < m;i++) C[i] + = c[i-1]; for(i = n1; I >=0; i--) Sa[--c[x[i]] =i; for(j =1, p =1; P < n; J <<=1, 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]-K; for(i =0; I < n; i++) W[i] =X[y[i]]; for(i =0; I < m; i++) C[i] =0; for(i =0; I < n; i++) c[w[i]]++; for(i =0; I < m; i++) C[i] + = c[i-1]; for(i = n1; I >=0; i--) Sa[--c[w[i]] =Y[i]; Swap (x, y); for(P =1, x[sa[0]] =0, i =1; I < n; i++) X[sa[i]]= CMP (y, sa[i-1], Sa[i], j)? P1: p++; if(P >= N) Break; M=p; }}CharS[MAXN], X[MAXN];intHEIGHT[MAXN], RK[MAXN];voidGetHeight (intN) { for(inti =1; i<= N; i++) Rk[sa[i] =i; for(inti =0, J, k =0; I < n; height[rk[i++]] =k) for(K. k--:0, j = Sa[rk[i]-1]; S[i+k] = = S[j+k]; k++);}intF[MAXN];voidGetfail (Char*p) {f[0] = f[1] =0; intn =strlen (P); for(inti =1; I < n;i++){ intj =F[i]; if(j && p[i]! = p[j]) j =F[j]; F[i+1] = (P[i] = = P[j]? j+1:0);//i+1 will be pushed to nth bit}}vector<int>Vec;voidFind (Char*t,Char*2) {vec.clear (); LL J=0, n = strlen (T), M =strlen (P); for(inti =0; I < n;i++){ while(j && t[i]! = p[j]) j =F[j]; if(T[i] = = P[j]) J + +; if(J = =m) {VEC.PB (i); J=0; I-= M-1; }} sort (Vec.begin (), Vec.end ());}intMain () {//freopen ("Data.txt", "R", stdin); //freopen ("OUT.txt", "w", stdout); intT, Kase =1; scanf ("%d",&u); while(t--) {scanf ("%s%s", X, S); intLen = strlen (S), M =strlen (X); S[len]='#'; s[len+1] =0; Build_sa (S,len+1,'Z'+1); GetHeight (len); Getfail (X); Find (S,X); VEC.PB (len); ll ans=0; REP1 (i,1, Len) { if(sa[i]+m-1> Len)Continue; intNXT = Lower_bound (Vec.begin (), Vec.end (), sa[i]+m-1) -Vec.begin (); Ans+ = Len-max (Vec[nxt],sa[i] +Height[i]); } printf ("Case #%d:%lld\n", kase++, ans); } return 0;}
HDU 5769 Substring suffix array + KMP