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