【Different Integers题解】
模板题,扔一个比较简洁的代码。
将指针起始位置定义在L=0,R=n+1,然后随着查询操作(l,r)进行移动,使得L=l,R=r。
需要注意的是查询的边界问题,l和r也包含在被查询的区间中。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, len;
int w[N], ans[N];
int get(int x) { return x / len; }
struct Query {
int id, l, r;
bool operator<(const Query a) const {
int i = get(l), j = get(a.l); // 块的编号
if (i != j) return i < j;
return r < a.r;
}
} q[N];
int cnt[N];
void add(int x, int& res) {
if (!cnt[x]) res++;
cnt[x]++;
}
void del(int x, int& res) {
cnt[x]--;
if (!cnt[x]) res--;
}
int main() {
while (cin >> n >> m) {
memset(cnt, 0, sizeof cnt);
int res = 0;
for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
len = sqrt(n);
for (int i = 0; i < m; i++) {
int l, r;
scanf("%d%d", &l, &r);
q[i] = {i, l, r};
}
sort(q, q + m);
int R = n + 1, L = 0;// 双指针
for (int k = 0; k < m; k++) {
int id = q[k].id, l = q[k].l, r = q[k].r;
while (R < r) del(w[R++], res);
while (R > r) add(w[--R], res);
while (L < l) add(w[++L], res);
while (L > l) del(w[L--], res);
ans[id] = res;
}
for (int i = 0; i < m; i++) printf("%d\n", ans[i]);
}
return 0;
}