题目链接 HH的项链
这道题可以直接上主席树的模板
#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) typedef long long LL; const int N = 5e4 + 10;
const int M = 3e6 + 10; int n, tot, q, a[N];
int T[M], lson[M], rson[M], val[M];
int nxt[N], b[N];
int m; int build(int l, int r){
int rt = tot++;
val[rt] = 0;
int m = (l + r) >> 1;
if(l != r){
lson[rt] = build(l, m);
rson[rt] = build(m + 1, r);
}
return rt;
}
int update(int rt, int pos, int v){
int newrt = tot++, tmp = newrt;
int l = 1, r = n;
val[newrt] = val[rt] + v;
while(l < r)
{
int m = (l + r) >> 1;
if(pos <= m)
{
lson[newrt] = tot++;
rson[newrt] = rson[rt];
newrt = lson[newrt];
rt = lson[rt];
r = m;
}
else
{
rson[newrt] = tot++;
lson[newrt] = lson[rt];
newrt = rson[newrt];
rt = rson[rt];
l = m + 1;
}
val[newrt] = val[rt] + v;
}
return tmp;
} int query(int rt, int pos){
int ret = 0;
int l = 1, r = n;
while(pos > l){
int m = (l + r) >> 1;
if (pos <= m){
ret += val[rson[rt]];
rt = lson[rt];
r = m;
}
else{
l = m + 1;
rt = rson[rt];
}
}
return ret + val[rt];
} int ask(int l, int r){ return query(T[r], l); } void init(){
tot = 0;
memset(nxt, -1, sizeof(nxt));
rep(i, 1, n) b[i - 1] = a[i];
sort(b, b + n);
int cnt = unique(b, b + n) - b;
T[0] = build(1, n);
rep(i, 1, n){
int id = lower_bound(b, b + cnt, a[i]) - b;
if(nxt[id] == -1)
T[i] = update(T[i - 1], i, 1);
else{
int t = update(T[i - 1], nxt[id], -1);
T[i] = update(t, i, 1);
}
nxt[id] = i;
}
} int main(){ scanf("%d", &n);
rep(i, 1, n) scanf("%d", a + i); init();
scanf("%d", &m);
while (m--){
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", ask(x, y));
} return 0; }
当然用莫队算法也是可以做的
#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) typedef long long LL; const int N = 2e5 + 10; int belong[N];
int a[N], b[N], c[N], ans[N];
int n, m, l, r, cnt, BS;
int now = 0; struct node{
int l, r, id;
friend bool operator < (const node &a, const node &b){
return belong[a.l] == belong[b.l] ? belong[a.r] < belong[b.r] : belong[a.l] < belong[b.l];
}
} q[N]; int main(){ scanf("%d", &n);
BS = (int)sqrt(n + 0.5); rep(i, 1, n) scanf("%d", a + i), b[i] = a[i];
sort(b + 1, b + n + 1);
cnt = unique(b + 1, b + n + 1) - b - 1;
rep(i, 1, n) a[i] = lower_bound(b + 1, b + cnt + 1, a[i]) - b; scanf("%d", &m);
rep(i, 1, m){
scanf("%d%d", &q[i].l, &q[i].r);
q[i].id = i;
} rep(i, 1, n) belong[i] = (i - 1) / BS + 1;
sort(q + 1, q + m + 1); l = 0, r = 0;
rep(i, 1, m){
while (l > q[i].l){ --l; if (c[a[l]] == 0) ++now; ++c[a[l]]; }
while (r < q[i].r){ ++r; if (c[a[r]] == 0) ++now; ++c[a[r]]; } while (l < q[i].l){ --c[a[l]]; if (!c[a[l]]) --now; ++l; }
while (r > q[i].r){ --c[a[r]]; if (!c[a[r]]) --now; --r; } ans[q[i].id] = now;
} rep(i, 1, m) printf("%d\n", ans[i]);
return 0;
}