int mountain(int o) {
mx[o]=max(mx[lch],mx[rch]);
mn[o]=min(mn[lch],mn[rch]);
sum[o]=sum[lch]+sum[rch];
}
void build(int l,int r,int o) { //建树
if(l==r) {
mx[o]=mn[o]=sum[o]=a[l];
return ; }
build(l,mid,lch);
build(mid+1,r,rch);
mountain(o);
return ;
}
void push_down(int l,int r,int o) {//下放
if(add[o]) {
if(flag[o]) {
set[o]+=add[o];add[o]=0;
} else {
mn[lch]+=add[o]; mn[rch]+=add[o];
mx[lch]+=add[o]; mx[rch]+=add[o];
add[lch]+=add[o]; add[rch]+=add[o];
sum[lch]+=((LL)(mid-l+1))*add[o];
sum[rch]+=((LL)(r-mid))*add[o];
add[o]=0;
}
}
if(flag[o]) {
mn[lch]=mn[rch]=mx[lch]=mx[rch]=set[o];
set[lch]=set[rch]=set[o];
sum[lch]=(mid-l+1)*set[o];
sum[rch]=(r-mid)*set[o];
add[lch]=add[rch]=0;
flag[lch]=flag[rch]=1;
flag[o]=set[o]=0;
}
}
//区间加 [x,y] 每个数 + z
void add_work(int l,int r,int o) {
if(x<=l&&r<=y) {
add[o]+=z; mx[o]+=z; mn[o]+=z;
sum[o]+=((LL)(r-l+1))*z;
return ;
}
push_down(l,r,o);
if(mid>=x) add_work(l,mid,lch);
if(mid<y) add_work(mid+1,r,rch);
mountain(o);
}
//区间 [x,y] 每个数 变为 z
void set_work(int l,int r,int o) {
if(x<=l&&r<=y) {
add[o]=0; //把之前区间加覆盖
lag[o]=1;//表示此区间有修改
mx[o]=mn[o]=set[o]=z;
sum[o]=((LL)(r-l+1))*z;
return ;
}
push_down(l,r,o);//标记下放
if(mid>=x) set_work(l,mid,lch);
if(mid<y) set_work(mid+1,r,rch);
mountain(o);
}
//区间求和 查询 sum [x,y]
long long query_sum(int l,int r,int o) {
if(x<=l&&r<=y) return sum[o];
push_down(l,r,o);
LL s=0;
if(mid>=x) s=query_sum(l,mid,lch);
if(mid<y) s+=query_sum(mid+1,r,rch);
mountain(o);
return s;
}
// 查询 max [x,y]
long long query_max(int l,int r,int o) {
if(x<=l&&r<=y) return mx[o];
push_down(l,r,o);
LL s=-INF;
if(mid>=x) s=query_max(l,mid,lch);
if(mid<y) s=max(s,query_max(mid+1,r,rch));
mountain(o);
return s;
}
// 查询 min [x,y]
long long query_min(int l,int r,int o) {
if(x<=l&&r<=y) return mn[o];
push_down(l,r,o);
LL s=INF;
if(mid>=x) s=query_min(l,mid,lch);
if(mid<y) s=min(s,query_min(mid+1,r,rch));
mountain(o);
return s;
}