Title Link: BZOJ-3585
Problem analysis
Interval MEX, the smallest natural number that is not present in the interval.
So we use a MO team + chunking approach, using the team to maintain the number of occurrences of each number in the current interval.
Then the MEX with a sub-block, the weight of the block (obviously Mex must be less than or equal to N, the weight of greater than n is meaningless, can be ignored directly), each block size sqrt (n).
Then the number of a number in the interval is reduced to 0, and the type of the block it is in is reduced by one, and the number is similar when it is added.
Then enumerate each block, find the smallest number of non-existent blocks (that is, the number of species less than the number of numbers in the block), and then to this fast directly from one to find the first non-existent numbers.
In this way the complexity of the team and the complexity of the chunking are added, O (n^1.5) + O (n^1.5) = O (n^1.5).
Code
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath > #include <algorithm>using namespace std;const int maxn = 200000 + 5, MaxQ = 200000 + 5, MAXB = + 5;int N, M, Blksize, Maxblk;int A[MAXN], BLK[MAXN], L[MAXB], R[MAXB], ANS[MAXQ], CNT[MAXN], V[MAXB], size[maxb];struct Query{int IDX, L, R, v;} q[maxq];inline bool Cmp (query Q1, query Q2) {if (q1.v = = Q2.V) return Q1.R < Q2.r;return q1.v < Q2.V;} inline void Del_num (int x) {--cnt[x];if (cnt[x] = = 0)--v[blk[x]];} inline void Add_num (int x) {if (cnt[x] = = 0) ++v[blk[x]];++cnt[x];} void Pull (int f, int. x, int y) {if (x = = y) return;if (f = = 0) {if (x < y) {for (int i = x; i < y; ++i) del_num (A[i]);} else{for (int i = x-1; I >= y; i.) add_num (A[i]);}} Else{if (x < y) {for (int i = x + 1; i <= y; ++i) add_num (A[i]);} else{for (int i = x; i > y; i.) del_num (A[i]);}} int Get_ans () {int ret = n;for (int i = 1; I <= maxblk; ++i) if (V[i] < Size[i]) {for (int j = L[i]; J <= R[i]; ++J) if (cnt[j] = = 0) {ret = J;break;} break;} return ret;} int main () {scanf ("%d%d", &n, &m), for (int i = 1; I <= n; ++i) {scanf ("%d", &a[i]); if (A[i] > N) a[i] = n + 1;} blksize = (int) sqrt ((double) n), for (int i = 0; I <= N; ++i) Blk[i] = i/blksize + 1; MAXBLK = blk[n];for (int i = 1; I <= maxblk; ++i) {L[i] = (i-1) * blksize; R[i] = i * BlkSize-1; Size[i] = R[i]-l[i] + 1;} R[MAXBLK] = n; SIZE[MAXBLK] = n-l[maxblk] + 1;for (int i = 1; I <= m; ++i) {scanf ("%d%d", &Q[I].L, &Q[I].R); Q[i]. IDX = i; Q[I].V = q[i].l/blksize;} Sort (q + 1, q + M + 1, CMP), for (int i = Q[1].L; I <= q[1].r; ++i) Add_num (A[i]); ANS[Q[1]. IDX] = Get_ans (); for (int i = 2; I <= m; ++i) {if (Q[I].R <= q[i-1].l) {Pull (0, Q[I-1].L, Q[I].L); Pull (1, Q[I-1].R, Q[I].R);} Else{pull (1, Q[I-1].R, Q[I].R); Pull (0, Q[I-1].L, Q[I].L);} Ans[q[i]. IDX] = Get_ans ();} for (int i = 1; I <= m; ++i) printf ("%d\n", Ans[i]); return 0;}
[Bzoj 3585] Mex "MO Team + sub-block"