📚【模板】整体二分
整体二分就是把操作也二分。
#include <stdio.h>
#include <vector>
const int N = 262144;
struct OPT {
int type;
int x, y, k;
int id;
};
int n, m;
int tree[N];
int a[N], ans[N];
void insert(int pos,int val) {
for(;pos <= n;pos += pos&-pos)
tree[pos] += val;
}
int query(int pos) {
int res = 0;
for(;pos;pos &= pos-1)
res += tree[pos];
return res;
}
void devide(int l,int r,std :: vector<OPT> &q) {
std :: vector<OPT> lt;
std :: vector<OPT> rt;
int mid = (l+r)>>1;
if(r-l == 1) {
for(int i = 0;i < q.size();++i)
ans[q[i].id] = (q[i].type^1) ? ans[q[i].id] : l;
return;
} else if(q.empty())
return;
for(int i = 0;i < q.size();++i) {
if(q[i].type) {
int rk = query(q[i].y)-query(q[i].x-1);
if(rk >= q[i].k)
lt.push_back(q[i]);
else
rt.push_back(OPT{q[i].type,q[i].x,q[i].y,q[i].k-rk,q[i].id});
} else {
if(q[i].k < mid) {
insert(q[i].x,q[i].y);
lt.push_back(q[i]);
} else
rt.push_back(q[i]);
}
}
for(int i = 0;i < lt.size();++i)
if(!lt[i].type)
insert(lt[i].x,-lt[i].y);
devide(l,mid,lt);
devide(mid,r,rt);
}
std :: vector<OPT> q;
signed main() {
scanf("%d %d",&n,&m);
int size = 0;
for(int i = 1;i <= n;++i) {
scanf("%d",&a[i]);
q.push_back(OPT{0,i,1,a[i],0});
}
for(int outs = 1;outs <= m;++outs) {
int i, j, k, t;
char query[2];
scanf("%s %d",query,&i);
switch(query[0]) {
case 'Q' :
scanf("%d %d",&j,&k);
q.push_back(OPT{1,i,j,k,outs});
break;
case 'C' :
scanf("%d",&t);
q.push_back(OPT{0,i,-1,a[i],0});
a[i] = t;
q.push_back(OPT{0,i, 1,a[i],0});
break;
}
}
for(int i = 1;i <= m;++i)
ans[i] = -1;
devide(0,1000000000,q);
for(int i = 1;i <= m;++i)
if(ans[i] >= 0) printf("%d\n",ans[i]);
return 0;
}