Title:
gives a sequence of length N. M operations, Q represents the Kth largest value of the query interval, and C represents the number of modifying a position. Output the Kth largest value for each query.
answer:
Modifying the number at the ith position affects i~n. So each modification can be maintained with a tree-like array. Each node of the tree-like array represents a tree, and the corresponding positions can be added when statistical results are calculated.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 60010; int t; int n, m, num; int w[maxn]; int tot; int root[maxn]; char tt[2]; vector<int> v; struct ask { int t, l, r, v; }q[10010]; struct node { int l, r, sum; }tre[maxn*40]; int use[maxn], tree[maxn]; int getid(int x) { return lower_bound(v.begin(), v.end(), x)-v.begin()+1; } void update(int l, int r, int &x, int y, int pos, int val) { tre[ ++tot] = tre[y]; tre [tot] .sum + = val; x = tot; if(l==r) return ; int mid = l+r>>1; if(pos<=mid) update(l, mid, tre[x].l, tre[y].l, pos, val); else update(mid+1, r, tre[x].r, tre[y].r, pos, val); } void add(int x, int pos, int val) { while(x <= n) { update(1, num, tree[x], tree[x], pos, val); x += x&(-x); } } int sum(int x) { int res = 0; while(x) { res + = tre [tre [use [x]]. l] .sum; x -= x&(-x); } return res; } int query(int l, int r, int x, int y, int k, int ql, int qr) { if(l==r) return l; int mid = l+r>>1; int t = tre[tre[x].l].sum-tre[tre[y].l].sum+sum(qr)-sum(ql); if(t>=k) { for(int i = qr; i; i-=i&(-i)) use[i] = tre[use[i]].l; for(int i = ql; i; i-=i&(-i)) use[i] = tre[use[i]].l; return query(l, mid, tre[x].l, tre[y].l, k, ql, qr); } else { for(int i = qr; i > 0; i-=i&(-i)) use[i] = tre[use[i]].r; for(int i = ql; i > 0; i-=i&(-i)) use[i] = tre[use[i]].r; return query(mid+1, r, tre[x].r, tre[y].r, k-t, ql, qr); } } int main() { scanf("%d", &t); while(t--) { to = 0 ; v.clear(); memset(tree, 0, sizeof(tree)); scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", &w[i]); v.push_back(w[i]); } for(int i = 1; i <= m; i++) { scanf("%s%d%d", tt, &q[i].l, &q[i].r); if(tt[0]=='C') q[i].t = 0, v.push_back(q[i].r); else scanf("%d", &q[i].v), q[i].t = 1; } sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); num = v.size(); for(int i = 1; i <= n; i++) update(1, num, root[i], root[i-1], getid(w[i]), 1); for(int i = 1; i <= m; i++) { if(q[i].t) { for(int j = q[i].r; j; j-=j&(-j)) use[j] = tree[j]; for(int j = q[i].l-1; j; j-=j&(-j)) use[j] = tree[j]; printf("%d\n", v[query(1, num, root[q[i].r], root[q[i].l-1], q[i].v, q[i].l-1, q[i].r)-1]); } else { add(q[i].l, getid(w[q[i].l]), -1); add(q[i].l, getid(q[i].r), 1); w[q[i].l] = q[i].r; } } } }