Find the most repeating string, and if there are multiple solutions, ask for the smallest dictionary order.
I also followed the paper Ro chicory to brush this problem.
The first is to enumerate the length of a circular section L, if it appears two times, will certainly contain s[0], s[l], s[2l] these adjacent two.
Then enumerate the adjacent two, extending forward and backward as far as possible, assuming that the extension length is K, the number of repetitions is K/L + 1
Backward extension is very natural is to seek the LCP, this with RMQ pretreatment can be O (1) query.
The forward extension is to consider that the s[i*l] and s[(i+1) *l] that we enumerate are not necessarily the beginning of the string, so I-(k-i) positions are moved forward.
Why move forward so much, because of this, the length of the LCP is exactly the number of I multiples.
So move forward, then ask for LCP again, see if I-(k% i) so much, enough words, the number of repetitions of this string plus 1.
As for the smallest dictionary order, you have to use the height array to naturally bring the dictionary order. Record the maximum length of all repetitions and then enumerate by dictionary order, and output as soon as one group is found.
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 6 Const intMAXN =100000+Ten;7 CharS[MAXN];8 intN;9 intSA[MAXN], RANK[MAXN], HEIGHT[MAXN];Ten intT[MAXN], T2[MAXN], c[ the]; One A voidBuild_sa (intNintm) - { - intI, *x = t, *y =T2; the 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; A for(i = n-k; i < n; i++) y[p++] =i; at 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); inp =1; x[sa[0]] =0; - for(i =1; I < n; i++) toX[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; the } * } $ Panax Notoginseng voidbuild_height () - { the intK =0; + for(inti =1; I <= N; i++) Rank[sa[i] =i; A for(inti =0; I < n; i++) the { + if(k) k--; - intj = Sa[rank[i]-1]; $ while(S[i + K] = = S[j + K]) k++; $Height[rank[i]] =K; - } - } the - intd[maxn][ -];Wuyi the voidINIT_RMQ () - { Wu for(inti =0; I < n; i++) d[i][0] = Height[i +1]; - for(intj =1; (1<< j) <= N; J + +) About for(inti =0; i + (1<< j)-1< n; i++) $D[i][j] = min (d[i][j-1], D[i + (1<< (J-1))][j-1]); - } - - intRMQ (intLintR) A { + intK =0; the while( (1<< (k +1)) <= (R-l +1)) k++; - returnMin (D[l][k], d[r-(1<<K) +1][k]); $ } the the intLCP (intIintj) the { thei = Rank[i]-1; j = Rank[j]-1; - if(I >j) Swap (I, j); in returnRMQ (i +1, j); the } the About intA[MAXN], CNT, MAXL; the the intMain () the { + //freopen ("In.txt", "R", stdin); - the intKase =0;Bayi while(SCANF ("%s", s) = =1&& s[0] !='#') the { then =strlen (s); -BUILD_SA (n +1, the); - build_height (); the init_rmq (); the theCNT = MAXL =0; the for(inti =1; I < n; i++) - { the for(intj =0; j + i < n; J + =i) the { the intK = LCP (J, J +i);94 intt = k/i +1; the intleft = i-(k%i); the intHead = J-Left ; the if(Head >=0&& LCP (head, head + i) >= left) t++;98 if(T >Maxl) About { -CNT =0;101a[cnt++] =i;102MAXL =T;103 }104 if(t = = Maxl) a[cnt++] =i; the }106 }107 108 intLen =-1, St;109 for(inti =1; I <= n && len = =-1; i++) the {111 for(intj =0; J < CNT; J + +) the {113 intL =A[j]; the if(LCP (Sa[i], Sa[i] + L) >= (MAXL-1) *l) the { theLen =l;117St =Sa[i];118 Break;119 } - }121 }122 123printf"Case %d:", ++Kase);124 for(inti =0; I < Len * MAXL; i++) printf ("%c", S[st +i]); thePuts"");126 }127 - return 0;129}code June
POJ 3693 (suffix array) Maximum repetition substring