Question: There are n values to calculate the difference between the two adjacent values. At this time, there is a sequence of n-1 values. If this sequence is used as a string, find the longest repeated substring, the two substrings cannot overlap.
Analysis: suffix array solution. First, the second answer turns the question into a judgment question: Determine whether two substrings with k length are the same and do not overlap.
It can only be said that the suffix array is very powerful
PS: one of the eight men's questions .......
# Include <cstdio> # include <iostream> # include <cstring> # include <algorithm> using namespace std; # define N 22222 # define INF 0x7FFFFFFF/***** suffix array template *****/# define F (x)/3 + (x) % 3 = 1? 0: tb) // F (x) To find the starting position of suffix (x) of the original string in the new string # define G (x) <tb? (X) * 3 + 1 :( (x)-tb) * 3 + 2) // G (x) is the position of the new string suffix (x) in the original string, and F (x) are reciprocal operations int wa [N], wb [N], wv [N], WS [N]; int sa [N * 3]; // suffix smaller than I. The starting position is int rank1 [N] and height [N] in the source string. // rank the int r [N * 3] In the suffix arrangement with rank starting from I. // If the input is a string, used to calculate 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) {int I; for (I = 0; I <n; I ++) wv [I] = r [a [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 --) B [-- WS [wv [I] = a [I]; return;} // Note: To facilitate recursive processing, the size of the r array and sa array is 3 * n void dc3 (int * r, int * sa, int n, int m) {// The rn array stores the new recursive string, and the san array is Sa 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; // tbc indicates the number of suffixes where the modulo 3 is 1 or 2 at the starting position} 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 ;}// sorts all suffixes where the starting position modulo 3 is equal to 0 for (I = 0; I <tbc; I ++) {if (san [I] <tb) wb [ta ++] = san [I] * 3;} if (n % 3 = 1) // n % 3 = 1, special processing of suffix (n-1) wb [ta ++] = n-1; sort (r, wb, wa, ta, m ); for (I = 0; I <tbc; I ++) wv [wb [I] = G (san [I])] = I; // merge the sorting results of all suffixes and save them in the sa array 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 ++]; (; j <tbc; p ++) sa [p] = wb [j ++]; return ;}// height [I] = suffix (sa [I-1]) the longest public prefix of suffix (sa [I]), that is, the longest public prefix of the two adjacent suffixes void calheight (int * r, int * sa, int n) {int I, j, k = 0; for (I = 1; I <= n; I ++) rank1 [sa [I] = I; for (I = 0; I <n; height [rank1 [I ++] = k) for (k? K --: 0, j = sa [rank1 [I]-1]; r [I + k] = r [j + k]; k ++ );} bool judge (int k, int n) {int maxx = 0, minn = INF; for (int I = 2; I <= n; I ++) {if (height [I] <k) {maxx = 0; minn = INF;} else {maxx = max (sa [I], max (maxx, sa [I-1]); minn = min (sa [I], min (minn, sa [I-1]);} if (maxx-minn> = k) return true;} return false;} int main () {int n, t, tt; while (scanf ("% d", & n) {scanf ("% d", & tt); -- n; for (int I = 0; I <n; I + +) {Scanf ("% d", & t); r [I] = t-tt + 100; // avoid negative tt = t ;} r [n] = 0; dc3 (r, sa, n + 1,190); calheight (r, sa, n); // for (int I = 0; I <= n; I ++) cout <I <''