【学习笔记】整体二分

P3834 【模板】可持久化线段树 2

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;int n;
struct node{
	int x,y,k;
	int id;
	int type;
};
vector<node> f;
int ans[N];
int tree[N];
#define lowbit(x) x&-x
void update(int x,int d){
	while(x<=n){
		tree[x]+=d;
		x+=lowbit(x);
	}
}
int query(int x){
	int res=0;
	while(x){
		res+=tree[x];
		x-=lowbit(x);
	}
	return res;
}
void solve(int l,int r,vector<int> q){
	if(q.empty()) return ;
	if(l==r){
		for(auto g:q){
			if(f[g].type==2) ans[f[g].id]=l;
		}
		return ;
	}
	vector<int> ll,rr;
	int mid=l+r>>1;
	for(auto g:q){
		if(f[g].type==1){
			if(f[g].k<=mid){
				update(f[g].x,1);
				ll.push_back(g);
			}
			else{
				rr.push_back(g);
			}
		}
		else{
			int k=query(f[g].y)-query(f[g].x-1);
			if(k<f[g].k){
				f[g].k-=k;
				rr.push_back(g);
			}
			else ll.push_back(g);
		}
	}
	for(auto g:q){
		if(f[g].type==1&&f[g].k<=mid) update(f[g].x,-1);
	}
	solve(l,mid,ll);
	solve(mid+1,r,rr);
}
int main(){
	int m;cin>>n>>m;
	for(int i=1;i<=n;i++){
		int k;cin>>k;
		f.push_back({i,0,k,0,1});
	}
	for(int i=1;i<=m;i++){
		int l,r,k;cin>>l>>r>>k;
		f.push_back({l,r,k,i,2});
	}
	vector<int> q;
	for(int i=0;i<f.size();i++) q.push_back(i);
	solve(0,1e9,q);
	for(int i=1;i<=m;i++) cout<<ans[i]<<"\n";
	return 0;
}
posted @ 2025-12-15 15:25  Ming3398  阅读(0)  评论(0)    收藏  举报