Question: Find the child string with the most repeat times in a string that can be obtained by repeat. If multiple duplicates are the same, the smallest Lexicographic Order is output.
Solution: It's similar to the paper. I haven't understood it for a long time, but I finally understood it. Assume that the length of our unit string is l. Then, we divide the string into s [0], s [l], s [2 * l], and s [3 * l]. In this way, n/l segments can be divided by l. Enumerate a j, indicating that the current enumeration is at s [j * l]. What we need to do is to find suf [j * l] and suf [(j + 1) * l] lcp (rmq is used here and the query is o (1). If this lcp is k, we know that it starts from s [j * l, the number of repeat times in the unit of l is at least k/l + 1. Why? Think about what lcp means. But this is not necessarily the best, because if we push forward, there may be some of the same, then enumerate forward I, indicating that the first I is the same, always enumerate until it is different, or the additional length exceeds l (more than l is equivalent to the previous j ). At this time, our new lcp length k = k + I is correct. It is correct to use this k to calculate the repeat times. During the traversal process, we need to write down the l with the maximum number of repeat times, find the minimum Lexicographic Order, start with rank from small to large enumeration, and see if there is any written l, the string starting with the current is consistent with the maximum number of repeat times (it is determined again by lcp). Once the matching is found, it is output.
I didn't write a case. I was always wrong. I couldn't find the error. I ran into tears...
# Include <stdio. h> # include <string. h >#include <algorithm> # include <vector> using namespace std; const int maxn = 511111; int p [maxn]; int min (int a, int B) {return a <B? A: B;} int dp [25] [maxn], f [maxn], ans, fuck; vector <int> vec; struct Suf {int wa [maxn], wb [maxn], ws [maxn], wv [maxn]; int rank [maxn], hei [maxn], sa [maxn]; int cmp (int * r, int I, int j, int l) {return r [I] = r [j] & r [I + l] = r [j + l];} void da (int * r, int n, int m) {int * x = wa, * y = wb, * t; int I, j, k, p; 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 <m; I ++) ws [I] = 0; for (I = 0; I <n; I ++) ws [x [I] ++; for (I = 1; I <m; I ++) Ws [I] + = ws [I-1]; for (I = n-1; I> = 0; I --) sa [-- ws [x [y [I] = y [I]; for (t = x, x = y, y = t, x [sa [0] = 0, p = 1, I = 1; I <n; I ++) x [sa [I] = cmp (y, sa [I-1], sa [I], j )? P-1: p ++;} k = 0; for (I = 1; I <n; I ++) rank [sa [I] = I; for (I = 0; I <n-1; hei [rank [I ++] = k) for (k? K --: 0, j = sa [rank [I]-1]; r [I + k] = r [j + k]; k ++ );} void rmq (int n) {int I, j; for (I = 1; I <= n; I ++) dp [0] [I] = hei [I]; for (I = 1; I <= 20; I ++) for (j = 1; j + (1 <I)-1 <= n; j ++) dp [I] [j] = min (dp [I-1] [j], dp [I-1] [j + (1 <(I-1)]);} int query (int l, int r) {if (l> r) swap (l, r); l ++; // calculate the minimum value from height [l + 1] to height [r] if (l = r) return dp [0] [l]; int K = r-l + 1; return min (dp [f [k] [l], dp [f [k] [r-(1 <f [k]) + 1]);} void solve (int n, char * s) {rmq (n); int I, j, k, l, r; for (l = 1; l <n; l ++) for (j = 0; j <n/l; j ++) {int pos1 = j * l, pos2 = j * l + l; k = query (rank [pos1], rank [pos2]); I = 0; if (j! = 0) {while (I <l & s [pos1-i-1] = s [pos2-i-1]) I ++;} k + = I; int add = k/l + 1; if (add = ans) vec. push_back (l); if (add> ans) {ans = add; vec. clear (); vec. push_back (l) ;}} int flag; for (I = 1; I <= n; I ++) {flag = 0; for (j = 0; j <vec. size (); j ++) {l = vec [j]; k = query (I, rank [sa [I] + l]); if (k/l + 1 = ans) {for (r = 0; r <ans * l; r ++) printf ("% c ", s [sa [I] + r]); puts (""); flag = 1; break ;}} if (flag) break ;}} arr; char s1 [maxn]; int s [maxn]; int main () {int cas, n, I, j, ca = 0; j = 0; for (I = 1; I <maxn-1111; I ++) {if (I> 1 <j + 1) j ++; f [I] = j ;} scanf ("% d", & cas); while (cas --) {scanf ("% s", s1); if (s1 [0] = '#') break; vec. clear (); ans = 1; n = strlen (s1); int len = 0; for (I = 0; I <n; I ++) s [I] = s1 [I]; s [n] = 0; arr. da (s, n + 1,555); printf ("Case % d:", ++ ca); arr. solve (n, s1 );}}