Description
Write a program that takes a sequence of number and returns length of the longest repeated
subsequence. A repeated subsequence which repeats identically at least K times without overlaps.
For example 1 2 3 1 2 3 2 3 1 repeats 2 3 for three times.
subsequence. A repeated subsequence which repeats identically at least K times without overlaps.
For example 1 2 3 1 2 3 2 3 1 repeats 2 3 for three times.
Input
Line 1: The input contains a single integer T , the number of test cases.
Line 2: Two space-separated integers: N and K (1 <= n <= 50000), (2 <= k <= n)
Lines 3..N+2: N integers, one per line. The integer is between 0 and 10^9.
It is guaranteed that at least one subsequence is repeated at least K times.
Line 2: Two space-separated integers: N and K (1 <= n <= 50000), (2 <= k <= n)
Lines 3..N+2: N integers, one per line. The integer is between 0 and 10^9.
It is guaranteed that at least one subsequence is repeated at least K times.
Output
For each test case, the first line print the length n of the Longest Repeated Subsequence and the line 2…n+1 print the subsequence numbers.(if we have several subsequence with the same length output the lexicographic order smallest one). Separate output for adjacent cases with a single blank line.
Sample Input
1 8 2 1 2 3 2 3 2 3 1
Sample Output
2 23
后缀数组,二分长度+验证。
#include<set> #include<map> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<bitset> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define rep(i,j,k) for (int i = j; i <= k; i++) #define per(i,j,k) for (int i = j; i >= k; i--) #define loop(i,j,k) for (int i = j;i != -1; i = k[i]) #define lson x << 1, l, mid #define rson x << 1 | 1, mid + 1, r #define fi first #define se second #define mp(i,j) make_pair(i,j) #define pii pair<string,string> using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const double eps = 1e-8; const int INF = 0x7FFFFFFF; const int mod = 1e8; const int N = 3e5 + 10; const int read() { char ch = getchar(); while (ch<'0' || ch>'9') ch = getchar(); int x = ch - '0'; while ((ch = getchar()) >= '0'&&ch <= '9') x = x * 10 + ch - '0'; return x; } int T, cas = 0; struct Sa { int s[N], a[N], b[N]; int rk[2][N], sa[N], h[N], w[N], now, n, m, K; //int rmq[N][20], lg[N]; bool GetS() { scanf("%d%d", &n, &K); rep(i, 1, n) scanf("%d", &a[i]), s[i] = a[i]; sort(a + 1, a + n + 1); m = unique(a + 1, a + n + 1) - a; rep(i, 1, n) s[i] = lower_bound(a + 1, a + m, s[i]) - a; return true; } void getsa(int z, int &m) { int x = now, y = now ^= 1; rep(i, 1, z) rk[y][i] = n - i + 1; for (int i = 1, j = z; i <= n; i++) if (sa[i] > z) rk[y][++j] = sa[i] - z; rep(i, 1, m) w[i] = 0; rep(i, 1, n) w[rk[x][rk[y][i]]]++; rep(i, 1, m) w[i] += w[i - 1]; per(i, n, 1) sa[w[rk[x][rk[y][i]]]--] = rk[y][i]; for (int i = m = 1; i <= n; i++) { int *a = rk[x] + sa[i], *b = rk[x] + sa[i - 1]; rk[y][sa[i]] = *a == *b&&*(a + z) == *(b + z) ? m - 1 : m++; } } void getsa(int m) { //n = strlen(s + 1); rk[1][0] = now = sa[0] = s[0] = 0; rep(i, 1, m) w[i] = 0; rep(i, 1, n) w[s[i]]++; rep(i, 1, m) rk[1][i] = rk[1][i - 1] + (bool)w[i]; rep(i, 1, m) w[i] += w[i - 1]; rep(i, 1, n) rk[0][i] = rk[1][s[i]]; rep(i, 1, n) sa[w[s[i]]--] = i; rk[1][n + 1] = rk[0][n + 1] = 0; //多组的时候容易出bug for (int x = 1, y = rk[1][m]; x <= n && y <= n; x <<= 1) getsa(x, y); for (int i = 1, j = 0; i <= n; h[rk[now][i++]] = j ? j-- : j) { if (rk[now][i] == 1) continue; int k = n - max(sa[rk[now][i] - 1], i); while (j <= k && s[sa[rk[now][i] - 1] + j] == s[i + j]) ++j; } } /*void getrmq() { h[n + 1] = h[1] = lg[1] = 0; rep(i, 2, n) rmq[i][0] = h[i], lg[i] = lg[i >> 1] + 1; for (int i = 1; (1 << i) <= n; i++) { rep(j, 2, n) { if (j + (1 << i) > n + 1) break; rmq[j][i] = min(rmq[j][i - 1], rmq[j + (1 << i - 1)][i - 1]); } } } int lcp(int x, int y) { int l = min(rk[now][x], rk[now][y]) + 1, r = max(rk[now][x], rk[now][y]); return min(rmq[l][lg[r - l + 1]], rmq[r - (1 << lg[r - l + 1]) + 1][lg[r - l + 1]]); } */ bool check(int x, int &y) { int tot = 0; b[tot++] = sa[1]; for (int i = 2; i <= n + 1; i++) { if (i <= n&&h[i] >= x) b[tot++] = sa[i]; else { sort(b, b + tot); int now = -INF, cnt = 0; rep(k, 0, tot - 1) if (b[k] >= now + x) now = b[k], cnt++; if (cnt >= K) { y = sa[i - 1]; return true; } tot = 0; b[tot++] = sa[i]; } } return false; } void work() { GetS(); getsa(m); int l = 1, r = n, g; while (l <= r) { if (check(l + r >> 1, g)) l = (l + r >> 1) + 1; else r = (l + r >> 1) - 1; } check(r, g); printf("%d\n", r); rep(i, 1, r) printf("%d\n", a[s[g + i - 1]]); } }sa; int main() { T = read(); while (T--) { sa.work(); if (T) printf("\n"); } return 0; }