Title Link: BZOJ-2724
Problem analysis
This problem and BZOJ-2821 poetry that the problem is almost the same, is directly divided into blocks, each size sqrt (n), and then the number according to the first keyword, the position of the second keyword sorting, convenient after two points to find a value in a range of occurrences of the number of times.
Pre-F[I][J] is the answer from Block I to block J.
For each query, the whole block in the middle is done directly with the number of SQRTN levels that are preprocessed, at both ends, to find the number of occurrences of them in two points.
The complexity of each query is SQRTN * Logn.
Note: When writing code, there is a Cmp () that does not guarantee a two-way consistent error!! warning! Note that the Cmp_num () function in the code, even if you do not need a second keyword, because Num may have the same, you must add a second keyword to ensure that the results of the comparison are two-way consistent!
Code
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include < Cstring> #include <cmath>using namespace std;inline void Read (int &num) {char c; c = GetChar (); while (C < ' 0 ' | | C > ' 9 ') c = GetChar (); Num = C-' 0 '; c = GetChar (); while (c >= ' 0 ' && C <= ' 9 ') {num = num * + C-' 0 '; c = GetChar ();}} const int MAXN = 40000 + 5, maxblk = + 5;int N, M, Blksize, Totblk;int A[MAXN], TL[MAXN], T[MAXN], CNT[MAXN], l[maxblk ], r[maxblk], FIRST[MAXN], Last[maxn];int f[maxblk][maxblk], g[maxblk][maxblk];struct es{int Pos, Num, V;} e[maxn];inline bool Cmp_num (es e1, es E2) {if (E1. Num = = E2. Num) return E1. Pos < E2. Pos;return E1. Num < E2. Num;} inline bool Cmp_pos (es e1, es E2) {return e1. Pos < E2. Pos;} int getnum (int Num, int x, int y) {if (x > Y | | x > E[last[num]]. Pos | | Y < E[first[num]]. Pos) return 0;int L, R, Mid, p1, p2;l = First[num]; r = Last[num];while (L <= r) {mid = (L + r) >> 1;if(E[mid]. Pos >= x) {p1 = Mid;r = mid-1;} else L = mid + 1;} L = First[num]; r = Last[num];while (L <= r) {mid = (L + R) >> 1;if (E[mid]. Pos <= y) {P2 = Mid;l = mid + 1;} else R = mid-1;} return P2-P1 + 1;} int main () {Read (n); Read (m); for (int i = 1; I <= n; ++i) {Read (E[i]. Num); E[i]. Pos = i;} Sort (e + 1, e + n + 1, cmp_num), int v_index = 0;for (int i = 1; I <= n; ++i) {if (i = = 1 | | E[i]. Num > E[i-1]. Num) ++v_index; E[I].V = V_index; Tl[v_index] = E[i]. Num;} Sort (e + 1, e + n + 1, Cmp_pos), for (int i = 1; I <= n; ++i) A[i] = E[i].v;sort (e + 1, e + n + 1, cmp_num); for (int i = 1; I <= N; ++i) {if (first[e[i].v] = = 0) FIRST[E[I].V] = i; LAST[E[I].V] = i;} blksize = (int) sqrt ((double) n); TOTBLK = (n-1)/blksize + 1;for (int i = 1; I <= totblk; ++i) {L[i] = (i-1) * blksize + 1; R[i] = i * blksize;} R[TOTBLK] = n;for (int i = 1; I <= totblk; ++i) {for (int j = 1; j <= N; ++j) cnt[j] = 0;f[i][i-1] = 0; g[i][i-1 ] = 0;for (int j = i; j <= totblk; + +)j) {F[i][j] = f[i][j-1];g[i][j] = g[i][j-1];for (int k = l[j]; k <= r[j]; ++k) {++cnt[a[k]];if (Cnt[a[k]] > F[i] [J] | | (Cnt[a[k] [= F[i][j] && a[k] < g[i][j])) {F[i][j] = cnt[a[k]]; G[i][j] = A[k];}}} memset (CNT, 0, sizeof (CNT)), for (int i = 1; I <= n; ++i) t[i] = -1;int L, r, X, Y, Ct, Ans, Cu; Ans = 0;for (int i = 1; I <= m; ++i) {Read (L); Read (r); l = (l + Ans-1)% n + 1; R = (r + Ans-1)% n + 1;if (L > R) Swap (L, r); x = (L-1)/blksize + 1; if (l! = l[x]) ++x;y = (r-1)/blksize + 1; if (r = r[y])--y;if (x > Y) {Ct = 0; Ans = 0;for (int j = l; J <= R; ++j) {++cnt[a[j]];if (Cnt[a[j]] > Ct | | (Cnt[a[j]] = = Ct && A[j] < Ans) {Ct = cnt[a[j]]; Ans = A[j];}} for (int j = l; J <= R; ++j)--cnt[a[j];} else {Ct = f[x][y]; Ans = g[x][y];for (int j = l; j < l[x]; ++j) {++cnt[a[j]];if (t[a[j]] = = 1) t[a[j]] = Getnum (A[j], l[x], r[y]); CU = Cnt[a[j]] + t[a[j]];if (cu > Ct | | (Cu = = Ct && A[j] < Ans)) {Ct = Cu; Ans =A[J];}} for (int j = r; j > R[y];--j) {++cnt[a[j]];if (t[a[j]] = = 1) t[a[j]] = Getnum (A[j], l[x], r[y]); CU = Cnt[a[j]] + t[a[j]];if (cu > Ct | | (Cu = = Ct && A[j] < Ans)) {Ct = Cu; Ans = A[j];}} for (int j = l; j < l[x]; ++j) {--cnt[a[j]]; T[A[J]] =-1;} for (int j = r; j > R[y];--j) {--cnt[a[j]]; T[A[J]] =-1;}} ans = Tl[ans];p rintf ("%d\n", ans); return 0;}
[Bzoj 2724] [Violet 6] Dandelion "sub-block"