做了一上午的线段树模板,供参考!
struct segtree{
int q,m,n;
vector<int> mx,mn,lz,lzm,sum;
const vector<int>&a;
segtree(int sz,const vector<int>&_a):a(_a){
mx.assign(sz<<2,0);
mn.assign(sz<<2,0);
lz.assign(sz<<2,0);
lzm.assign(sz<<2,0);
sum.assign(sz<<2,0);
n=sz;
build(1,1,sz);
}
void pushup(int x){
sum[x]=sum[x<<1]+sum[(x<<1)+1];
mx[x]=max(mx[x<<1],mx[(x<<1)+1]);
mn[x]=min(mn[x<<1],mn[(x<<1)+1]);
}
void pushdown(int x,int l,int r){
int mid=(l+r)>>1;
sum[x<<1]=sum[x<<1]*lzm[x]+lz[x]*(mid-l+1),sum[(x<<1)+1]=sum[(x<<1)+1]*lzm[x]+lz[x]*(r-mid);
mx[x<<1]=mx[x<<1]*lzm[x]+lz[x],mx[(x<<1)+1]=mx[(x<<1)+1]*lzm[x]+lz[x];
mn[x<<1]=mn[x<<1]*lzm[x]+lz[x],mn[(x<<1)+1]=mn[(x<<1)+1]*lzm[x]+lz[x];
if(mn[x<<1]>mx[x<<1])swap(mn[x<<1],mn[x<<1]);
if(mn[x<<1|1]>mx[x<<1|1])swap(mn[x<<1|1],mn[x<<1|1]);
lz[x<<1]=lz[x<<1]*lzm[x]+lz[x],lz[(x<<1)+1]=lz[(x<<1)+1]*lzm[x]+lz[x];
lzm[x<<1]*=lzm[x],lzm[(x<<1)+1]*=lzm[x];
lz[x]=0;
lzm[x]=1;
}
void build(int x,int l,int r){
lzm[x]=1;
if(l==r){
sum[x]=a[l];
mn[x]=a[l];
mx[x]=a[l];
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build((x<<1)+1,mid+1,r);
pushup(x);
}
int qsum(int tl,int tr){return qsum(1,tl,tr,1,n);}
int qsum(int x,int tl,int tr,int l,int r){
if(tl<=l&&r<=tr)return sum[x];
int mid=(l+r)>>1,res=0;
pushdown(x,l,r);
if(tr>mid)res+=qsum((x<<1)+1,tl,tr,mid+1,r);
if(tl<=mid)res+=qsum(x<<1,tl,tr,l,mid);
return res;
}
int qmax(int tl,int tr){return qmax(1,tl,tr,1,n);}
int qmax(int x,int tl,int tr,int l,int r){
if(tl<=l&&r<=tr)return mx[x];
int mid=l+r>>1,res=-0x3f3f3f3f3f3f3f3f;
pushdown(x,l,r);
if(tr>mid)res=max(res,qmax((x<<1)+1,tl,tr,mid+1,r));
if(tl<=mid)res=max(res,qmax(x<<1,tl,tr,l,mid));
return res;
}
int qmin(int tl,int tr){return qmin(1,tl,tr,1,n);}
int qmin(int x,int tl,int tr,int l,int r){
if(tl<=l&&r<=tr)return mn[x];
int mid=l+r>>1,res=0x3f3f3f3f3f3f3f3f;
pushdown(x,l,r);
if(tr>mid)res=min(res,qmin((x<<1)+1,tl,tr,mid+1,r));
if(tl<=mid)res=min(res,qmin(x<<1,tl,tr,l,mid));
return res;
}
void add(int t,int pl){add(1,t,t,1,n,pl);}
void add(int tl,int tr,int pl){add(1,tl,tr,1,n,pl);}
void add(int x,int tl,int tr,int l,int r,int pl){
if(tl<=l&&r<=tr){
lz[x]+=pl;
sum[x]+=(r-l+1)*pl;
mx[x]+=pl;
mn[x]+=pl;
return;
}
int mid=(l+r)>>1;
pushdown(x,l,r);
if(tr>mid)add((x<<1)+1,tl,tr,mid+1,r,pl);
if(tl<=mid)add(x<<1,tl,tr,l,mid,pl);
pushup(x);
return;
}
void times(int t,int tm){times(1,t,t,1,n,tm);}
void times(int tl,int tr,int tm){times(1,tl,tr,1,n,tm);}
void times(int x,int tl,int tr,int l,int r,int tm){
if(tl<=l&&r<=tr){
lzm[x]*=tm;
lz[x]*=tm;
sum[x]*=tm;
mx[x]*=tm;
mn[x]*=tm;
if(tm<0)swap(mx[x],mn[x]);
return;
}
int mid=(l+r)>>1;
pushdown(x,l,r);
if(tr>mid)times((x<<1)+1,tl,tr,mid+1,r,tm);
if(tl<=mid)times(x<<1,tl,tr,l,mid,tm);
pushup(x);
return;
}
};