题目
思路
莫队板子,统计数字出现次数。
Code
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 1000001
int n, m, a[M], ans[M];
int sqrn, num[M], cnt[M];
struct query {
int x, y, id;
friend bool operator < (query q1, query q2) {
if (num[q1.x] == num[q2.x]) return q1.y < q2.y;
return num[q1.x] < num[q2.x];
}
}q[M];
void add(int x, int &now) {
++cnt[x];
if (cnt[x] == 1) ++now;
}
void del(int x, int &now) {
--cnt[x];
if (cnt[x] == 0) --now;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
scanf("%d", &m), sqrn = n / sqrt(m);
for (int i = 1; i <= n; ++i) num[i] = (i - 1) / sqrn + 1;
for (int i = 1; i <= m; ++i) {
scanf("%d %d", &q[i].x, &q[i].y);
q[i].id = i;
}
std::sort(q + 1, q + m + 1);
int l = 1, r = 1, now = 1;
cnt[a[1]] = 1;
for (int i = 1; i <= m; ++i) {
while (l > q[i].x) add(a[--l], now);
while (r < q[i].y) add(a[++r], now);
while (l < q[i].x) del(a[l++], now);
while (r > q[i].y) del(a[r--], now);
ans[q[i].id] = now;
}
for (int i = 1; i <= m; ++i) printf("%d
", ans[i]);
return 0;
}