zhanweijie edited 1 年,8 月前
#define inf 0x3fffffff
#include<bits/stdc++.h>
using namespace std;
struct ST{
int covertag,max,min,sum,addtag;
}tree[2000040];
int a[500010],ans1,ans2;
void build(int l,int r,int x){
tree[x].addtag=0;
tree[x].covertag=inf;
if (l==r){
tree[x].sum=a[l];
tree[x].max=a[l];
tree[x].min=a[l];
return ;
}
int mid=l+r>>1;
build(l,mid,x<<1);build(mid+1,r,x<<1|1);
tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
tree[x].max=max(tree[x<<1].max,tree[x<<1|1].max);
tree[x].min=min(tree[x<<1].min,tree[x<<1|1].min);
}
void Pushdown(int l,int r,int x){
int mid=l+r>>1;
if (tree[x].covertag!=inf){
tree[x<<1].max=tree[x].covertag;
tree[x<<1|1].max=tree[x].covertag;
tree[x<<1].min=tree[x].covertag;
tree[x<<1|1].min=tree[x].covertag;
tree[x<<1].covertag=tree[x].covertag;
tree[x<<1].addtag=0;
tree[x<<1].sum=tree[x].covertag*(l-mid+1);
tree[x<<1|1].covertag=tree[x].covertag;
tree[x<<1|1].addtag=0;
tree[x<<1|1].sum=tree[x].covertag*(r-mid);
tree[x].covertag=inf;
}
if (tree[x].addtag!=0){
tree[x<<1].addtag+=tree[x].addtag;
tree[x<<1|1].addtag+=tree[x].addtag;
tree[x<<1].sum+=tree[x].addtag*(l-mid+1);
tree[x<<1|1].sum+=tree[x].addtag*(r-mid);
tree[x<<1].max+=tree[x].addtag;
tree[x<<1|1].max+=tree[x].addtag;
tree[x<<1].min+=tree[x].addtag;
tree[x<<1|1].min+=tree[x].addtag;
tree[x].addtag=0;
}
}
//[lq,rq] -- q
void cover(int lq,int rq,int q,int l,int r,int x){
if (lq<=l&&rq>=r){
tree[x].covertag=q;
tree[x].max=q;
tree[x].min=q;
tree[x].addtag=0;
tree[x].sum=q*(r-l+1);
return ;
}
Pushdown(l,r,x);
int mid=l+r>>1;
if (lq<=mid) cover(lq,rq,q,l,mid,x<<1);
if (rq>mid) cover(lq,rq,q,mid+1,r,x<<1|1);
tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
tree[x].max=max(tree[x<<1].max,tree[x<<1|1].max);
tree[x].min=min(tree[x<<1].min,tree[x<<1|1].min);
}
//[lq,rq] +q;
void add(int lq,int rq,int q,int l,int r,int x){
if (lq<=l&&rq>=r){
tree[x].addtag+=q;
tree[x].max+=q;
tree[x].min+=q;
tree[x].sum+=q*(r-l+1);
return ;
}
Pushdown(l,r,x);
int mid=l+r>>1;
if (lq<=mid) add(lq,rq,q,l,mid,x<<1);
if (rq>mid) add(lq,rq,q,mid+1,r,x<<1|1);
tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
tree[x].max=max(tree[x<<1].max,tree[x<<1|1].max);
tree[x].min=min(tree[x<<1].min,tree[x<<1|1].min);
}
//[lq,rq] sum
int query(int lq,int rq,int l,int r,int x){
if (lq<=l&&rq>=r){
ans1=max(ans1,tree[x].max);
ans2=min(ans2,tree[x].min);
return tree[x].sum;
}
Pushdown(l,r,x);
int mid=l+r>>1,sum=0;
if (lq<=mid) sum+=query(lq,rq,l,mid,x<<1);
if (rq>mid) sum+=query(lq,rq,mid+1,r,x<<1|1);
tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
tree[x].max=max(tree[x<<1].max,tree[x<<1|1].max);
tree[x].min=min(tree[x<<1].min,tree[x<<1|1].min);
return sum;
}
int main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n,1);
int q;
cin>>q;
for (int i=1;i<=q;i++)
{
int k,l,r,d;
scanf("%d",&k);
if (k==1)
{
scanf("%d%d%d",&l,&r,&d);
add(l,r,d,1,n,1);
}
if (k==2)
{
scanf("%d%d%d",&l,&r,&d);
cover(l,r,d,1,n,1);
}
if (k==3)
{
long long ans=0;
ans1=-inf;
ans2=inf;
scanf("%d%d",&l,&r);
ans=query(l,r,1,n,1);
printf("%lld %d %d\n",ans,ans1,ans2);
}
}
return 0;
}