2
Tips on how to solve problems:
Little ho: How to solve this problem?
Little hi: Well, this time the problem is called the longest non-overlapping duplicate substring problem.
Small ho: And the last question seems to be, but this time is not overlapping, the direct use of the last algorithm seems to not work well.
Little hi: Yes. The crux of the problem is that the direct use of the height array does not guarantee that the two suffixes do not overlap, we have to change the thinking.
Little ho: Can you split the answer and turn it into a judgment question?
Little hi: It's a good idea, it's really doable. Let's take a two-minute k, which means we assume that there are non-overlapping repeating substrings of length k in the string.
Little ho: Well, that's what it means.
Small hi: The existence of a non-repeating substring of length k is equivalent to the existence of two suffixes with a public prefix of length k (there is no requirement for no overlap). We check which values in the height array are ≥k. And if there is a continuous height value ≥k, the corresponding suffix is divided into the same group. This ensures that the longest common prefix between all suffix 22 in the group is no less than K.
Let's take a sample example to look at the situation of k=2 and k=3.
x |
I |
Height |
k=2 |
k=3 |
1 |
8 |
0 |
|
|
1 2 3 2 3 2 3 1 |
1 |
1 |
|
|
2 3 1 |
6 |
0 |
|
|
2 3 2) 3 1 |
4 |
2 |
>=2 |
|
2 3 2 3 2 3 1 |
2 |
4 |
>=2 |
>=3 |
3 1 |
7 |
0 |
|
|
3 2 3 1 |
5 |
1 |
|
|
3 2 3 2 3 1 |
3 |
3 |
>=2 |
>=3 |
As you can see, when k=2, the public prefixes of "231" and "23231" are greater than or equal to K, the public prefixes of "23231" and "2323231" are also greater than the equivalent k, so these 3 consecutive suffixes are divided into a group. Similarly, "3231" and "323231" are also divided into groups.
For k=3, "23231" and "2323231" are divided into a group, "3131" and "323231" are divided into a group.
Little ho: I know!
Little hi: Yes, that's right! Let's see if we can find duplicate substrings that don't overlap. For each group, we check the SA value corresponding to these suffixes (that is, the suffix starting point in the original string position I). If Max{sa}-min{sa} >= K, then it means we can find a set of duplicate substrings that do not overlap.
For example, for k=3, the SA value for "23231" and "2323231" is 4 and 2, and the SA value for "3131" and "323231" is 5 and 3, and the difference does not satisfy the value greater than or equal to 3, so no overlap is found.
For k=2, the first set of max{sa}-min{sa}=6-2=4 satisfies greater than or equal to 2, so it is possible to find non-overlapping.
We give the following C + + code:
BOOL Check (int K) {for (int i=1;i<=n;i++) if (height[i]< K) { minsa=sa[i]; Maxsa=sa[i]; } else { minsa=min (minsa,sa[i]); Maxsa=max (Maxsa,sa[i]); if (maxsa-minsa>=k) return true; } return false;}
Little ho: Haha, it's not hard, I'm going to make it right now!
#include <iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<string>#include<map>#include<stack>#include<queue>#include<vector>#defineINF 2e9#defineMet (b) memset (a,b,sizeof a)typedefLong Longll;using namespacestd;Const intN = 2e5+5;Const intM = 4e5+5;intcmpint(RNintAintBintl) {return(R[a]==r[b]) && (r[a+l]==r[b+l]);}intWa[n],wb[n],wss[n],wv[n];intRank[n];//The rank of suffix i in sa[]intHeight[n];//Sa[i] and Sa[i-1] LCPintSa[n];//Sa[i] Indicates the subscript for the small suffix of the rank ivoidDA (int(RNint*sa,intNintm) {//r[] For the initial input, you can change to a string array, sa[] is a suffix array, n is the input number +1,m is the maximum value in the input, the character can be corresponding to the ASCII code maximum value intI, J, p, *x = WA, *y = WB, *T; for(i =0; i<m; i++) Wss[i] =0; for(i =0; i<n; i++) Wss[x[i] = r[i]]++; for(i =1; i<m; i++) wss[i] + = wss[i-1]; for(i = n-1; I >=0; i--) Sa[--wss[x[i]] =i; for(j =1, p =1; p<n; J *=2, 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]-J; for(i =0; i<n; i++) Wv[i] =X[y[i]]; for(i =0; i<m; i++) Wss[i] =0; for(i =0; i<n; i++) wss[wv[i]]++; for(i =1; i<m; i++) wss[i] + = wss[i-1]; for(i = n-1; I >=0; i--) sa[--wss[wv[i]] [y[i];//Base Sort Section for(t = x, x = y, y = t, p =1, x[sa[0]] =0, i =1; i<n; i++) X[sa[i]]= CMP (y, Sa[i-1], Sa[i], j)? P-1: p++; }}voidCalheight (int*r,intN) {//here n is the actual length intI, j, k =0; for(i =1; I <= N; i++) Rank[sa[i] =i; for(i =0; i<n; height[rank[i++]] =k) for(K. k--:0, j = Sa[rank[i]-1]; R[i + K] = = R[j + K]; k++);}intn,m;intAa[n];intmaxx=1, minn=1;BOOLSolveintk) { for(intI=1; i<=n; i++) { if(height[i]<k) {Minn=maxx=Sa[i]; } Else{Maxx==Max (maxx,sa[i]); Minn=min (minn,sa[i]); if(maxx-minn>=k)return true; } } return false;}intMain () {scanf ("%d",&N); for(intI=0; i<n; i++) scanf ("%d",&Aa[i]); DA (Aa,sa,n+1,1024x768); Calheight (Aa,n); intL=0, r=n,ans=-1;; while(l<=r) {intMid= (l+r) >>1; if(Solve (mid)) ans=mid,l=mid+1; Elser=mid-1; } printf ("%d\n", ans); return 0;}