[SDOI2009] HH necklace
Original title link [SDOI2009] HH necklace
Subject to the effect
You \ (n \) number, give your \ (q \) once asked, every time you ask for \ (l, r \) , ask you \ (l, r \) How many different numbers have
Topic solution to a problem
This question analysis we found that, for a \ ([L_1, R_1] \ ) there is another \ ([L_2, R_1] \ ) and \ (L_2 \) is strictly greater than \ (L_1 \) , then there must first the number of different intervals than or equal to the second number of different sections, where it is clear that there is a equal situation, what is equal ? In \ ([L_2, R_1] \ ) contains the number of \ ([L_1, L_2 - 1 ] \) number included in the latter are the number of the former. Then we find for such a case \ ([L_1, L_2 - 1 ] \) would be no need to exist. But note that here we are strictly defined \ (R_1 \) are the same and \ (L_1 <L_2 \) , we continue to push discover \ (R_2> R_1 \) also qualified.
So we get if we press the right queries range from small to large, so the problem can be transformed into a prefix and a linear, we use the data structure on whether to maintain every 1 or 0 as after, if it is an explanation the same number does not appear, if there have been described as one, each time the processing position to the query \ (R & lt \) , then query data structure \ (sum_R - sum_ {l - 1} \) values can be obtained our answer
Here we use Fenwick tree maintenance, the following code
//#define fre yes
#include <cstdio>
#include <algorithm>
const int N = 1000005;
struct Node {
int l, r;
int pos;
} w[N];
int Vis[N], arr[N], ans[N];
int tree[N];
bool cmp(Node x, Node y) {
return x.r < y.r;
}
int lowbit(int x) {
return x & (-x);
}
int n;
void change(int x, int k) {
while(x <= n) {
tree[x] += k;
x += lowbit(x);
}
}
int sum(int x) {
int res = 0;
while(x > 0) {
res += tree[x];
x -= lowbit(x);
} return res;
}
int main() {
static int q;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &arr[i]);
}
scanf("%d", &q);
for (int i = 1; i <= q; i++) {
int l, r;
scanf("%d %d", &l, &r);
w[i].l = l; w[i].r = r;
w[i].pos = i;
}
std::sort(w + 1, w + 1 + q, cmp);
int tot = 1;
for (int i = 1; i <= q; i++) {
for (int j = tot; j <= w[i].r; j++) {
if(Vis[arr[j]]) change(Vis[arr[j]], -1);
change(j, 1);
Vis[arr[j]] = j;
}
tot = w[i].r + 1;
ans[w[i].pos] = sum(w[i].r) - sum(w[i].l - 1);
}
for (int i = 1; i <= q; i++) {
printf("%d\n", ans[i]);
} return 0;
}