Dynamic Rankings ZOJ - 2112

Dynamic Rankings ZOJ - 2112

题意:

给你个长度为n的数组有q次每次询问让你求[l, r]的第k大或将a[x] 修改为y.

题解:

A: 这题我怎么一直段错误?

B: 你是不是和上一题一样用动态开点建主席树?

A:是的!

B: 这样肯定过不了, 这题应该将前n个数据直接建一个普通的主席树, 后面q次询问再建树状数组的主席树。

A:这样啊。

#include<bits/stdc++.h>
using namespace std;

const int M = 2000000;
const int N = 10007;
#define m (l + r) / 2

struct hjt{
    int sum, l, r;
}tree[M];

struct qu{
    int l, r, k;
}que[N];

vector<int> no, la, g;

int n, q, t, a[500007], top = 1, rt[500007], root[500007];

int get_id(int x) {
    return lower_bound(g.begin(), g.end(), x) - g.begin() + 1;
}



void update(int v, int pos, int last, int &now, int l, int r) {
    now = top++;
    tree[now] = tree[last];
    tree[now].sum += v;
    if (l == r) return;
    if (pos <= m) update(v, pos, tree[last].l, tree[now].l, l, m);
    else update(v, pos, tree[last].r, tree[now].r, m + 1, r);
}

int query(int k, int last, int now, int l, int r) {
    if (l == r) return l;
    int sum = tree[tree[now].l].sum - tree[tree[last].l].sum;
    for (int i = 0; i < no.size(); i++) {
        sum += tree[tree[no[i]].l].sum;
    }
    for (int i = 0; i < la.size(); i++) {
        sum -= tree[tree[la[i]].l].sum;
    }
    if (sum >= k) {
        for (int i = 0; i < no.size(); i++) {
            no[i] = tree[no[i]].l;
        }
        for (int i = 0; i < la.size(); i++) {
            la[i] = tree[la[i]].l;
        }
        return query(k, tree[last].l, tree[now].l, l, m);
    }
    for (int i = 0; i < no.size(); i++) {
        no[i] = tree[no[i]].r;
    }
    for (int i = 0; i < la.size(); i++) {
        la[i] = tree[la[i]].r;
    }
    return query(k - sum, tree[last].r, tree[now].r, m + 1, r);

}

int lowbit(int x) {
    return x & -x;
}



int main(){
    scanf("%d", &t);
    while (t--) {
        top = 1;
        scanf("%d %d", &n, &q);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            g.push_back(a[i]);
        }
        for (int i = 1; i <= q; i++) {
            char op;
            scanf(" %c", &op);
            if (op == 'Q') {
                scanf("%d %d %d", &que[i].l, &que[i].r, &que[i].k);
            } else {
                scanf("%d %d", &que[i].l, &que[i].r);
                que[i].k = -1;
                g.push_back(que[i].r);
            }
        }
        sort(g.begin(), g.end());
        g.erase(unique(g.begin(), g.end()), g.end());
        for (int i = 1; i <= n; i++) {
            int va = get_id(a[i]);
            update(1, va, rt[i - 1], rt[i], 1, (int)g.size());
        }
        for (int i = 1; i <= q; i++) {
            if (que[i].k == -1) {
                int va = get_id(a[que[i].l]);
                for (int j = que[i].l; j <= n; j += lowbit(j)) {
                    update(-1, va, root[j], root[j], 1, (int)g.size());
                }
                a[que[i].l] = que[i].r;
                va = get_id(que[i].r);
                for (int j = que[i].l; j <= n; j += lowbit(j)) {
                    update(1, va, root[j], root[j], 1, (int)g.size());
                }
            }else{
                la.clear(), no.clear();
                for (int j = que[i].r; j; j -= lowbit(j)) {
                    no.push_back(root[j]);
                }
                for (int j = que[i].l - 1; j; j -= lowbit(j)) {
                    la.push_back(root[j]);
                }
                printf("%d\n", g[query(que[i].k, rt[que[i].l- 1], rt[que[i].r], 1, (int)g.size()) - 1]);

            }
        }
        for (int i = 0; i <= top; i++) {
            tree[i].l = tree[i].r = tree[i].sum = 0;
        }
        for (int i = 0; i <= n; i++) {
            rt[i] = root[i] = 0;
        }


    }
   }
posted @ 2020-07-10 15:12  ccsu_zhaobo  阅读(32)  评论(0编辑  收藏  举报