📚【模板】整体二分

整体二分就是把操作也二分。

#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;
}
posted @ 2022-08-02 11:11  bikuhiku  阅读(20)  评论(0编辑  收藏  举报