【学习笔记】整体二分
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;
}

浙公网安备 33010602011771号