题目链接:https://vjudge.net/problem/ZOJ-2112
题意:能修改的查询第k大
学习博客:https://blog.csdn.net/WilliamSun0122/article/details/77885781
理解:修改pos位置x - >y的话,影响的是【pos,n】,所以用树状数组的思想维护,然后对于每个节点建立可持久化线段树,由x变为y的话就是x位置减一,y位置加一,复杂度:nlognlogn
#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
#define lowbit(x) (x & (-x))
struct node1 {
char op[2];
int x, y, k;
}q[N];
struct node2 {
int l, r;
int val;
}tree[N * 40];
int n, m;
int a[N], c[N], b[N * 2], len;
int tot;
int root[N], rot[N];
int ul[N], ur[N];
int update1(int pre, int l, int r, int pos, int val) {
int cur = ++tot;
tree[cur] = tree[pre];
tree[cur].val += val;
if(l == r) return cur;
int mid = (l + r) >> 1;
if(pos <= mid) tree[cur].l = update1(tree[pre].l, l, mid, pos, val);
else tree[cur].r = update1(tree[pre].r, mid + 1, r, pos, val);
return cur;
}
void update2(int pos, int x, int val) {
while(pos <= n) {
rot[pos] = update1(rot[pos], 1, len, x, val);
pos += lowbit(pos);
}
}
int query(int pl, int pr, int rtl, int rtr, int l, int r, int k) {
if(l == r) return l;
int res = tree[tree[rtr].l].val - tree[tree[rtl].l].val;
for(int i = pr; i >= 1; i -= lowbit(i)) res += tree[tree[ur[i]].l].val;
for(int i = pl; i >= 1; i -= lowbit(i)) res -= tree[tree[ul[i]].l].val;
int mid = (l + r) >> 1;
if(res >= k) {
for(int i = pr; i >= 1; i -= lowbit(i)) ur[i] = tree[ur[i]].l;
for(int i = pl; i >= 1; i -= lowbit(i)) ul[i] = tree[ul[i]].l;
return query(pl, pr, tree[rtl].l, tree[rtr].l, l, mid, k);
} else {
for(int i = pr; i >= 1; i -= lowbit(i)) ur[i] = tree[ur[i]].r;
for(int i = pl; i >= 1; i -= lowbit(i)) ul[i] = tree[ul[i]].r;
return query(pl, pr, tree[rtl].r, tree[rtr].r, mid + 1, r, k - res);
}
}
int main() {
int T;
int tmp;
scanf("%d", &T);
while(T--) {
scanf("%d %d", &n, &m);
len = 0;
tot = 0;
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[++len] = a[i], c[i] = a[i];
for(int i = 1; i <= m; i++) {
scanf("%s", q[i].op);
if(q[i].op[0] == 'Q') {
scanf("%d %d %d", &q[i].x, &q[i].y, &q[i].k);
} else {
scanf("%d %d", &q[i].x, &q[i].y);
a[q[i].x] = q[i].y;
b[++len] = q[i].y;
}
}
sort(b + 1, b + 1 + len);
len = unique(b + 1, b + 1 + len) - (b + 1);
for(int i = 1; i <= n; i++) {
tmp = lower_bound(b + 1, b + 1 + len, c[i]) - b;
root[i] = update1(root[i - 1], 1, len, tmp, 1);
rot[i] = 0;
}
for(int i = 1; i <= m; i++) {
if(q[i].op[0] == 'C') {
tmp = lower_bound(b + 1, b + 1 + len, c[q[i].x]) - b;
update2(q[i].x, tmp, -1);
c[q[i].x] = q[i].y;
tmp = lower_bound(b + 1, b + 1 + len, c[q[i].x]) - b;
update2(q[i].x, tmp, 1);
} else {
for(int j = q[i].x - 1; j >= 1; j -= lowbit(j)) ul[j] = rot[j];
for(int j = q[i].y; j >= 1; j -= lowbit(j)) ur[j] = rot[j];
printf("%d\n", b[query(q[i].x - 1, q[i].y, root[q[i].x - 1], root[q[i].y], 1, len, q[i].k)]);
}
}
}
return 0;
}