Given a string, find the longest repeated substring that appears at least K times. The k substrings can overlap.
The occurrence of K times means that this sub-string appears in any K places and does not require that the K is continuous.
Then, according to Luo's thesis, use the suffix array to solve the problem.
Second answer, and then use the height array to determine whether at least K of the seed string exists
[Cpp]
# Include <iostream>
# Include <algorithm>
# Include <cstring>
# Include <string>
# Include <cstdio>
# Include <cmath>
# Include <queue>
# Include <map>
# Include <set>
# Define eps 1e-5
# Define maxn20005
# Define MAXM 1000005
# Define INF 00000000000007ll
Using namespace std;
Int r [MAXN];
Int wa [MAXN], wb [MAXN], wv [MAXN], tmp [MAXM];
Int sa [MAXN]; // index range 1 ~ N value range 0 ~ N-1
Int cmp (int * r, int a, int B, int l)
{
Return r [a] = r [B] & r [a + l] = r [B + l];
}
Void da (int * r, int * sa, int n, int m)
{
Int I, j, p, * x = wa, * y = wb, * ws = tmp;
For (I = 0; I <m; I ++) ws [I] = 0;
For (I = 0; I <n; I ++) ws [x [I] = r [I] ++;
For (I = 1; I <m; I ++) ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- ws [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 ++) ws [I] = 0;
For (I = 0; I <n; I ++) ws [wv [I] ++;
For (I = 1; I <m; I ++) ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- ws [wv [I] = y [I];
For (swap (x, y), 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 ++;
}
}
Int rank [MAXN]; // index range 0 ~ N-1 value range 1 ~ N
Int height [MAXN]; // index from 1 (height [1] = 0)
Void calheight (int * r, int * sa, int n)
{
Int I, 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 );
Return;
}
Int n, k;
Bool check (int mid)
{
Int cnt = 1;
For (int I = 1; I <= n; I ++)
{
If (height [I] <mid) cnt = 1;
Else cnt ++;
If (cnt> = k) return 1;
}
Return 0;
}
Int main ()
{
Int m = 0;
Scanf ("% d", & n, & k );
For (int I = 0; I <n; I ++)
{
Scanf ("% d", & r [I]);
R [I] ++;
M = max (m, r [I]);
}
R [n] = 0;
Da (r, sa, n + 1, m + 1 );
Calheight (r, sa, n );
Int res = 0;
Int left = 1, right = n;
While (left <= right)
{
Int mid = (left + right)> 1;
If (check (mid ))
{
Left = mid + 1;
Res = max (res, mid );
}
Else right = mid-1;
}
Printf ("% d \ n", res );
Return 0;
}
# Include <iostream>
# Include <algorithm>
# Include <cstring>
# Include <string>
# Include <cstdio>
# Include <cmath>
# Include <queue>
# Include <map>
# Include <set>
# Define eps 1e-5
# Define maxn20005
# Define MAXM 1000005
# Define INF 00000000000007ll
Using namespace std;
Int r [MAXN];
Int wa [MAXN], wb [MAXN], wv [MAXN], tmp [MAXM];
Int sa [MAXN]; // index range 1 ~ N value range 0 ~ N-1
Int cmp (int * r, int a, int B, int l)
{
Return r [a] = r [B] & r [a + l] = r [B + l];
}
Void da (int * r, int * sa, int n, int m)
{
Int I, j, p, * x = wa, * y = wb, * ws = tmp;
For (I = 0; I <m; I ++) ws [I] = 0;
For (I = 0; I <n; I ++) ws [x [I] = r [I] ++;
For (I = 1; I <m; I ++) ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- ws [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 ++) ws [I] = 0;
For (I = 0; I <n; I ++) ws [wv [I] ++;
For (I = 1; I <m; I ++) ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- ws [wv [I] = y [I];
For (swap (x, y), 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 ++;
}
}
Int rank [MAXN]; // index range 0 ~ N-1 value range 1 ~ N
Int height [MAXN]; // index from 1 (height [1] = 0)
Void calheight (int * r, int * sa, int n)
{
Int I, 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 );
Return;
}
Int n, k;
Bool check (int mid)
{
Int cnt = 1;
For (int I = 1; I <= n; I ++)
{
If (height [I] <mid) cnt = 1;
Else cnt ++;
If (cnt> = k) return 1;
}
Return 0;
}
Int main ()
{
Int m = 0;
Scanf ("% d", & n, & k );
For (int I = 0; I <n; I ++)
{
Scanf ("% d", & r [I]);
R [I] ++;
M = max (m, r [I]);
}
R [n] = 0;
Da (r, sa, n + 1, m + 1 );
Calheight (r, sa, n );
Int res = 0;
Int left = 1, right = n;
While (left <= right)
{
Int mid = (left + right)> 1;
If (check (mid ))
{
Left = mid + 1;
Res = max (res, mid );
}
Else right = mid-1;
}
Printf ("% d \ n", res );
Return 0;
}