Topic links
Test instructions: A string containing only lowercase letters for a given length of N (n <= 1000), and the number of different substrings at least two times without overlapping of string substrings;
Input
AAAAAbabcabbaaaaaa #Output233 idea: The suffix array is applied to solve the SA array and the height array, and then the common prefix length I of the enumeration suffix, because it cannot overlap, so the adjacent height does not satisfy the LCP >= I. write an understanding of the postfix array multiplication algorithm:1. If you want the value of the SA array is also 1~n need to add a minimum and not appear in the last character ' # ', Inside y[] is to use the SA array to reorder the second keyword, because of the use of the radix sort, so the current length is k the same substring, the next time when the 2*k is long, The SA to which Y is ranked in front of the subscript is to be small;2. In the GetHeight function, Rk[i]: The suffix i rank in the sa; Height[i] represents the public prefix length of s[i] and s[i-1]. And the value of s[i] and S[j] is RMQ (min{Height[i+1]...height[j]}), plus I < J, and can be obtained by means of auxiliary array h[i] = Height[rk[i]], and H[i] >= h[i-1] + 1; The time complexity of solving height[] can be reduced to O (n) by recursion;Note: After adding a character at the end of the input string s n = strlen (s) + 1; When solving rk[], Sa[i] is starting from 1, sa[0] = ' $ '; after the solution height[] or starting from 0; details
#include <bits/stdc++.h>using namespaceStd;typedefLong Longll;Const intMAXN =1007;CharS[MAXN];intSa[maxn],t[maxn],t2[maxn],c[maxn],n;voidBuild_sa (intMintN//m is the maximum value of the ASCII code for characters +1;n = strlen (s) + 1;{ intI,*x = T, *y =T2; for(i =0; i < m; i++) C[i] =0; for(i =0; i < n; i++) C[x[i] = s[i]]++; for(i =1; i < m; i++) C[i] + = c[i-1]; for(i = n-1; I >=0; i--) Sa[--c[x[i]] =i; for(intK =1; k <= N;k <<=1){ intp =0; for(i = N-k;i < n;i++) y[p++] =i; for(i =0; i < n;i++)if(Sa[i] >= k) y[p++] = Sa[i]-K; for(i =0; i < m;i++) C[i] =0; for(i =0; i < n;i++) c[x[y[i]]]++; 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]; Swap (x, y); x[sa[0]] =0;//converts a character into a sequence number; for(i =1, p =1; I < n;i++) X[sa[i]]= Y[sa[i]] = = y[sa[i-1]] && y[sa[i]+k] = = y[sa[i-1]+k]?p-1:p + +; if(P >= N) Break; M=p; }}intRK[MAXN],HEIGHT[MAXN];voidgetheight () {intI,j,k =0; for(i =1; I <= n;i++) rk[sa[i]] = i;//Rk[i]: subscript of suffix I in sa[], starting from 1 for(i =0; I < n;i++){ if(k) k--; if(Rk[i] = =0)Continue; J= Sa[rk[i]-1]; while(I+k<n && j+k<n && s[i+k] = = S[j+k]) k++; Height[rk[i]]= k;//H[i] = height[rk[i]]; H[i] >= h[i-1]-1; }}intMain () { while(SCANF ("%s", s) = =1&& s[0] !='#') {ll ans=0; N=strlen (s); S[n]='#'; Build_sa ('Z'+1, n+1); GetHeight (); for(inti =1; I <= n/2; i++){ intL = n+1, R =-1; for(intj =2; J <= n;j++){ if(Height[j] >= i) {//The best left-hand l,r is introduced;r = Max (R,max (sa[j],sa[j-1])); L= Min (L,min (sa[j],sa[j-1])); } Else{ if(R-l >= i) ans++; R= -1, L = n+1; } } if(R-l >= i) ans++; } printf ("%i64d\n", ans); } return 0;}
Hdu 3518 boring counting suffix array LCP