#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,(rt<<1|1)
#define INF 1000000100
const int maxn = 1000010;
int sum[maxn<<2],MIN[maxn<<2],MAX[maxn<<2],add[maxn<<2];
void pushUP(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
MIN[rt]=min(MIN[rt<<1],MIN[rt<<1|1]);
}
void maintain(int l,int r,int rt){
sum[rt]=MIN[rt]=MAX[rt]=0;
if(r>l) pushUP(rt);
sum[rt]+=add[rt]*(r-l+1); MAX[rt]+=add[rt]; MIN[rt]+=add[rt];
}
void build(int l,int r,int rt){
add[rt]=0;
if(l==r){
scanf("%d",&sum[rt]);
add[rt]=MAX[rt]=MIN[rt]=sum[rt];
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushUP(rt);
}
int ql,qr,addv;
void update(int l,int r,int rt){
if(ql<=l&&r<=qr){
add[rt]+=addv;
}
else {
int m=(l+r)>>1;
if(ql<=m) update(lson);
if(qr >m) update(rson);
}
maintain(l,r,rt);
}
int sum_,min_,max_;
void query(int l,int r,int rt,int ADD){
if(ql<=l&&r<=qr){
sum_+=sum[rt]+ADD*(r-l+1);
min_= min(min_,ADD+MIN[rt]);
max_= max(max_,ADD+MAX[rt]);
}
else {
int m=(l+r)>>1;
if(ql<=m) query(lson,ADD+add[rt]);
if(qr >m) query(rson,ADD+add[rt]);
}
}
int main()
{
int n,Q;
while(scanf("%d %d",&n,&Q)==2){
build(1,n,1);
while(Q--){
int cmd;
scanf("%d",&cmd);
if(cmd==1){
scanf("%d %d %d",&ql,&qr,&addv);
update(1,n,1);
}
else {
scanf("%d %d",&ql,&qr);
sum_=0; min_=INF; max_=-INF;
query(1,n,1,0);
cout<<sum_<<" "<<min_<<" "<<max_<<endl;
}
}
}
return 0;
}
线段树 add操作(无惰性标记)
最新推荐文章于 2018-11-13 20:29:51 发布