CF940F Machine Learning 题解 带修莫队
题目链接:https://www.luogu.com.cn/problem/CF940F
带修莫队 模板题。
求 mex 的部分可以暴力。逻辑完全参考自 ouuan 大佬的博客
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, M, Q, blo, a[maxn], ans[maxn], idx1, idx2;
unordered_map<int, int> mp;
int cnt1[maxn*2], cnt2[maxn];
struct Query {
int id, l, r, t;
} query[maxn];
struct Event {
int p, c;
} event[maxn];
void add(int c) {
cnt2[ cnt1[c] ]--;
cnt1[c]++;
cnt2[ cnt1[c] ]++;
}
void del(int c) {
cnt2[ cnt1[c] ]--;
cnt1[c]--;
cnt2[ cnt1[c] ]++;
}
int mex() {
for (int i = 1; ; i++)
if (!cnt2[i])
return i;
}
void lsh() {
vector<int> v;
for (int i = 1; i <= n; i++) v.push_back(a[i]);
for (int i = 1; i <= idx2; i++) v.push_back(event[i].c);
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 1; i <= n; i++) a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1;
for (int i = 1; i <= idx2; i++) event[i].c = lower_bound(v.begin(), v.end(), event[i].c) - v.begin() + 1;
}
int main() {
scanf("%d%d", &n, &Q);
M = sqrt(n * 2) + 5;
blo = pow(n, 2.0/3);
for (int i = 1; i <= n; i++)
scanf("%d", a+i);
for (int i = 0; i < Q; i++) {
int op;
scanf("%d", &op);
if (op == 1) { // 1 l r
int l, r;
scanf("%d%d", &l, &r);
idx1++;
query[idx1] = {idx1, l, r, idx2};
}
else { // 2 p c
int p, c;
scanf("%d%d", &p, &c);
event[++idx2] = {p, c};
}
}
lsh(); // 离散化
sort(query+1, query+idx1+1, [](auto a, auto b) {
if (a.l / blo != b.l / blo)
return a.l < b.l;
if (a.r / blo != b.r / blo)
return a.r < b.r;
return a.t < b.t;
});
for (int i = 1, l = 1, r = 0, t = 0; i <= idx1; i++) {
while (l < query[i].l) del(a[l++]);
while (l > query[i].l) add(a[--l]);
while (r < query[i].r) add(a[++r]);
while (r > query[i].r) del(a[r--]);
for (; t < query[i].t; t++) {
auto [p, c] = event[t+1];
int x = a[p];
if (p >= l && p <= r) {
del(x);
add(c);
}
a[p] = c;
event[t+1].c = x;
}
for (; t > query[i].t; t--) {
auto [p, c] = event[t];
int x = a[p];
if (p >= l && p <= r) {
del(x);
add(c);
}
a[p] = c;
event[t].c = x;
}
ans[ query[i].id ] = mex();
}
for (int i = 1; i <= idx1; i++)
printf("%d\n", ans[i]);
return 0;
}
浙公网安备 33010602011771号