Codeforces 940F Machine Learning (带修改莫队)
题目链接 Codeforces Round #466 (Div. 2) Problem F
题意 给定一列数和若干个询问,每一次询问要求集合$\left\{c_{0}, c_{1}, c_{2}, c_{3}, ...,c_{10^{9}}\right\}$的$mex$
同时伴有单点修改的操作。
根据题目询问的这个集合的性质可以知道答案不会超过$\sqrt{n}$,那么每次询问的时候直接暴力找就可以了。
剩下的都是可修改莫队的基本操作。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) const int N = 1e5 + 10; int c[N], f[N << 1], vis[N], ans[N]; int a[N], b[N], d[N << 1]; int n, m, bs, et; int cnt = 0, tot = 0; int op, x, y; int l, r; int net, ret; struct node{ int l, r, lb, rb, id, x; friend bool operator < (const node &a, const node &b){ if (a.lb != b.lb) return a.lb < b.lb; if (a.rb != b.rb) return a.rb < b.rb; return a.x < b.x; } } q[N]; struct upd{ int pos, x, y; } e[N]; void update(int x){ if (vis[x]){ --c[f[a[x]]]; --f[a[x]]; ++c[f[a[x]]]; } else{ --c[f[a[x]]]; ++f[a[x]]; ++c[f[a[x]]]; } vis[x] ^= 1; } void change(int pos, int x){ if (vis[pos]){ update(pos); a[pos] = x; update(pos); } else a[pos] = x; } int main(){ scanf("%d%d", &n, &m); bs = pow(n, 2. / 3.); bs = max(bs, 1); rep(i, 1, n) scanf("%d", a + i), d[++et] = a[i]; rep(i, 1, m){ scanf("%d%d%d", &op, &x, &y); if (op == 1){ ++cnt; q[cnt].l = x; q[cnt].r = y; q[cnt].lb = (x - 1) / bs + 1; q[cnt].rb = (y - 1) / bs + 1; q[cnt].id = cnt; q[cnt].x = tot; } else{ ++tot; e[tot].pos = x; e[tot].y = y; d[++et] = y; } } sort(d + 1, d + et + 1); net = unique(d + 1, d + et + 1) - d - 1; rep(i, 1, n) a[i] = lower_bound(d + 1, d + net + 1, a[i]) - d; rep(i, 1, tot) e[i].y = lower_bound(d + 1, d + net + 1, e[i].y) - d; rep(i, 1, n) b[i] = a[i]; rep(i, 1, tot){ e[i].x = b[e[i].pos]; b[e[i].pos] = e[i].y; } sort(q + 1, q + cnt + 1); l = 1, r = 0, x = 0; rep(i, 1, cnt){ while (x < q[i].x){ ++x; change(e[x].pos, e[x].y); } while (x > q[i].x){ change(e[x].pos, e[x].x); --x; } while (r < q[i].r) update(++r); while (r > q[i].r) update(r--); while (l > q[i].l) update(--l); while (l < q[i].l) update(l++); rep(j, 1, 1e5) if (!c[j]){ ret = j; break;} ans[q[i].id] = ret; } rep(i, 1, cnt) printf("%d\n", ans[i]); return 0; }