莫队
莫队也是 OI 👴发明的一种离线区间处理问题
这篇讲的挺好的
复杂度 \(O(n\sqrt n)\)
查询区间内数的种数。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m, a[N], belong[N], cnt[N], ans[N], t;
struct node {
int l, r, id;
}q[N];
int main() {
scanf("%d", &n);
t = sqrt(n);
for (int i = 1; i <= n; i++) scanf("%d", a + i);
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d", &q[i].l, &q[i].r);
q[i].id = i;
}
sort(q + 1, q + 1 + m, [&](node a, node b) {
int x = (a.l - 1) / t, y = (b.l - 1) / t;
return x == y ? a.r < b.r : x < y;
});
int l = 1, r = 0, now = 0;
for (int i = 1; i <= m; i++) {
int ql = q[i].l, qr = q[i].r;
while (l < ql) now -= !--cnt[a[l++]];
while (l > ql) now += !cnt[a[--l]]++; //第一次出现
while (r < qr) now += !cnt[a[++r]]++; //第一次出现
while (r > qr) now -= !--cnt[a[r--]]; //若没了则减掉
ans[q[i].id] = now;
}
for (int i = 1; i <= m; i++) {
printf("%d\n", ans[i]);
}
}