[SDOI2009] HH necklace "Fenwick tree."

[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;
}

Guess you like

Origin www.cnblogs.com/Nicoppa/p/11479310.html