/***************************************: Given a string, the longest repeated substring that appears at least K times can overlap; Algorithm Analysis: This question is similar to pku1743. It is also the first two answers, and then the suffix is divided into several groups; that is, the height array is obtained with the suffix array; then, the height array is used to divide the sorted suffixes into several groups. different numbers of Suffixes in a group must be determined not to be smaller than K; if there are K identical substrings that meet the conditions, otherwise they do not exist; **************************************** * *****************/# include <iostream> # include <cstring> # include <cstdlib> # include <cstdio> # include <climits> # include <algorithm> using namespace STD; const int n = 20010; const int M = 1000010; // the maximum value of the r array # define f (x) (X)/3 + (X) % 3 = 1? 0: Tb) # define g (x) <TB? (X) * 3 + 1 :( (x)-TB) * 3 + 2) int wa [N], WB [N], WV [N], _ ws [m]; int C0 (int * r, int A, int B) {return R [a] = R [B] & R [A + 1] = R [B + 1] & R [A + 2] = R [B + 2];} int C12 (int K, int * r, int A, int B) {If (k = 2) return R [a] <R [B] | r [a] = R [B] & C12 (1, R, A + 1, B + 1 ); else return R [a] <R [B] | r [a] = R [B] & WV [A + 1] <WV [B + 1];} void sort (int * r, int * a, int * B, int N, int m) {for (INT I = 0; I <n; I ++) WV [I] = R [A [I]; for (INT I = 0; I <m; I ++) _ ws [I] = 0; for (INT I = 0; I <n; I ++) _ ws [wv [I] ++; For (INT I = 1; I <m; I ++) _ ws [I] + = _ ws [I-1]; for (INT I = n-1; I> = 0; I --) B [-- _ ws [wv [I] = A [I]; return;} void DC3 (int * r, int * Sa, int N, int m) {int I, j, * rn = R + N, * San = SA + N, TA = 0, TB = (n + 1)/3, TBC = 0, P; R [N] = R [n + 1] = 0; for (I = 0; I <n; I ++) {if (I % 3! = 0) wa [TBC ++] = I;} Sort (R + 2, WA, WB, TBC, m); sort (R + 1, WB, WA, TBC, m); sort (R, WA, WB, TBC, m); For (P = 1, RN [F (WB [0])] = 0, I = 1; I <TBC; I ++) {rn [F (WB [I])] = C0 (R, WB [I-1], WB [I])? P-1: P ++;} If (P <TBC) DC3 (RN, San, TBC, P); else {for (I = 0; I <TBC; I ++) san [Rn [I] = I ;}for (I = 0; I <TBC; I ++) {If (San [I] <TB) WB [ta ++] = San [I] * 3;} If (N % 3 = 1) WB [ta ++] = n-1; sort (R, WB, wa, Ta, m); for (I = 0; I <TBC; I ++) WV [WB [I] = g (San [I])] = I; for (I = 0, j = 0, P = 0; I <TA & J <TBC; P ++) {SA [p] = C12 (WB [J] % 3, R, wa [I], WB [J])? Wa [I ++]: WB [J ++] ;}for (; I <ta; P ++) SA [p] = wa [I ++]; for (; j <TBC; P ++) SA [p] = WB [J ++]; return;} int rank [N], height [N]; 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 check (int n, int K, int mid) {int S = 1; for (INT I = 1; I <= N; I ++) {If (height [I] >=mid) {s ++; If (S> = k) return 1 ;}else S = 1 ;}return 0 ;} int R [N * 3], sa [N * 3]; int main () {// freopen ("C: \ Users \ Administrator \ Desktop \ kd.txt "," r ", stdin); int N, K; scanf (" % d ", & N, & K); For (INT I = 0; I <n; I ++) {scanf ("% d", & R [I]);} R [N] = 0; DC3 (R, SA, n + 1, m); calheight (R, SA, n); int min = 1; int max = N; while (Min <= max) {int mid = (min + max)> 1; if (check (n, k, mid) min = Mid + 1; else max = mid-1;} printf ("% d \ n", max); return 0 ;}