最小值查询
int ql,qr;//查询[ql,qr]最小值
int query(int o,int l,int r){
int m=l+(l+r)/2,ans=INF;
if(ql<=l&&qr>=r) return minv[o];//包含
if(ql<=m) ans=min(ans,query(o*2,l,m));//left
if(m<qr) ans=min(ans,query(o*2+1,m+1,r));//right
return ans;
}
点修改
int p,v;
void updata(int o,int l,int r){
int m=l+(l+r)/2;
if(l==r) minv[o]=v;//叶节点
else{
if(p<=m) updata(o*2,l,m);//左子树
else updata(o*2+1,m+1,r);//右子树
minv[o]=min(minv[o*2],minv[o*2+1]);
}
}
信息维护
void maintain(int o,int l,int r){
int lc=o*2,rc=o*2+1;
sumv[o]=minv[o]=maxv[o]=0;
if(r>l){
sumv[o]=sumv[lc,rc];
minv[o]=min(minv[lc],minv[rc]);
maxv[o]=max(maxv[lc],maxv[rc]);
}
minv[o]+=addv[o];maxv[o]+=addv[o];sumv[o]+=addv*(r-l+1);
}
add操作
void updata(int o,int l,int r){
int lc=o*2,rc=o*2+1;
if(y1<=l&&y2>=r){
addv[o]+=v;
}
else{
int m=l+(l+r)/2;
if(y1<=m) updata(lc,l,m);
if(y2>m) updata(rc,m+1,r);
}
maintain(o,l,r);//维护区间信息
}
区间查询
int _min,_max,_sum;
void query(int o,int l,int r,int add){
if(y1<=l&&r2>=r){
_sum+=sumv[o]+add*(r-l+1);
_min=min(_min,minv[o]+add);
_max=max(_max,maxv[o]+add);
}
else{
int m=l+(l+r)/2;
if(y1<=m) query(o*2,l,m,add+addv[o]);
if(y2>m) query(o*2+1,m+1,r,add+addv[o]);
}
}
区间全部修改
void updata(int o,int l,int r){
int lc=o*2,rc=lc+1;
if(y1<=l&&y2>=r){
setv[o]=v;
}else{
pushdown(o);
int m=l+(l+r)/2;
if(y1<=m) updata(lc,l,m);
if(y2>m) updata(rc,m+1,r);
}
maintain(o,l,r);
}
标记传递
void pushdown(o){
int lc=o*2,rc=lc+1;
if(setv[o]>=0){
setv[lc]=setv[rc]=setv[o];
setv[o]=-1;//清除标记
}
}
set的区间查询
int _min,_max,_sum;
void query(int o,int l,int r){
if(setv[o]>=0){
_sum+=setv[o]*(min(r,y2)-max(l,y1)+1);
_min=min(_min,setv[o]);
_max=max(_max,setv[o]);
}
else if(y1<=l&&r2>=r){
_sum+=sumv[o];
_min=min(_min,minv[o]);
_max=max(_max,maxv[o]);
}
else{
int m=l+(l+r)/2;
if(y1<=m) query(o*2,l,m);
if(y2>m) query(o*2+1,m+1,r);
}
}