双懒惰标记的题目。类似于维护序列,还要简单些。
#include<bits/stdc++.h>
#define maxn (100000+5)
#define LL long long
#define inf 2147483547
using namespace std;
struct Tree
{
LL sum,min,max,set,add;
}a[maxn*3];
LL n,Q,x,lp,rp,v;
char ch;
inline LL read()
{
ch=getchar();
LL num=0,flag=1;
while(ch<'0'||ch>'9'){if(ch=='-')flag=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){num=(num<<3)+(num<<1)+ch-'0';ch=getchar();}
return flag*num;
}
void up(LL p,LL l,LL r)
{
LL lc=p<<1,rc=(p<<1)+1;
if(r>l)
{
a[p].max=max(a[lc].max,a[rc].max);
a[p].min=min(a[lc].min,a[rc].min);
a[p].sum=a[lc].sum+a[rc].sum;
}
}
void down(LL p,LL l,LL r)
{
LL lc=p<<1,rc=(p<<1)+1,m=l+((r-l)>>1);
if(a[p].set!=inf)
{
a[lc].max=a[rc].max=a[lc].min=a[rc].min=a[lc].set=a[rc].set=a[p].set;
a[lc].sum=(m-l+1)*a[p].set;
a[rc].sum=(r-m)*a[p].set;
a[p].set=inf;
a[lc].add=a[rc].add=a[p].add=0;
}
if(a[p].add)
{
if(a[lc].set==inf)a[lc].add+=a[p].add;else a[lc].set+=a[p].add;
if(a[rc].set==inf)a[rc].add+=a[p].add;else a[rc].set+=a[p].add;
a[lc].min+=a[p].add,a[rc].min+=a[p].add,
a[lc].max+=a[p].add,a[rc].max+=a[p].add,
a[lc].sum+=(m-l+1)*a[p].add,
a[rc].sum+=(r-m)*a[p].add,
a[p].add=0;
}
}
void build(LL p,LL l,LL r)
{
if(l==r)
{
scanf("%lld",&x),a[p]=(Tree){x,x,x,-1,0};
return;
}
LL m=l+((r-l)>>1),lc=p<<1,rc=(p<<1)+1;
build(lc,l,m);
build(rc,m+1,r);
a[p].set=inf;
up(p,l,r);
return;
}
void update_add(LL p,LL l,LL r)
{
LL lc=p<<1,rc=(p<<1)+1;
if(lp<=l&&r<=rp)
{
a[p].max+=v;
a[p].min+=v;
a[p].sum+=(r-l+1)*v;
if(a[p].set!=inf)
{
a[p].set+=v;return;
}
a[p].add+=v;
}
else
{
LL m=l+((r-l)>>1);
down(p,l,r);
if(lp<=m)update_add(lc,l,m);
if(rp>m)update_add(rc,m+1,r);
up(p,l,r);
}
}
void update_set(LL p,LL l,LL r)
{
LL lc=p<<1,rc=(p<<1)+1;
if(lp<=l&&r<=rp)
{
a[p].min=a[p].max=a[p].set=v;
a[p].sum=(r-l+1)*v,a[p].add=0;
}
else
{
down(p,l,r);
LL m=l+((r-l)>>1);
if(lp<=m)update_set(lc,l,m);
if(rp>m)update_set(rc,m+1,r);
up(p,l,r);
}
}
LL query_sum(LL p,LL l,LL r)
{
if(lp<=l&&r<=rp)return a[p].sum;
LL m=l+((r-l)>>1),lc=p<<1,rc=(p<<1)+1,ans=0;
down(p,l,r);
if(lp<=m)ans+=query_sum(lc,l,m);
if(rp>m)ans+=query_sum(rc,m+1,r);
up(p,l,r);
return ans;
}
LL query_max(LL p,LL l,LL r)
{
if(lp<=l&&r<=rp)return a[p].max;
LL m=l+((r-l)>>1),lc=p<<1,rc=(p<<1)+1,ans=-0x7f3f3f3f;
down(p,l,r);
if(lp<=m)ans=max(ans,query_max(lc,l,m));
if(rp>m)ans=max(ans,query_max(rc,m+1,r));
up(p,l,r);
return ans;
}
LL query_min(LL p,LL l,LL r)
{
if(lp<=l&&r<=rp)return a[p].min;
LL m=l+((r-l)>>1),lc=p<<1,rc=(p<<1)+1,ans=0x7f3f3f3f;
down(p,l,r);
if(lp<=m)ans=min(ans,query_min(lc,l,m));
if(rp>m)ans=min(ans,query_min(rc,m+1,r));
up(p,l,r);
return ans;
}
void work()
{
char s[10];
for(LL i=1;i<=Q;i++)
{
scanf("%s",&s);
lp=read();rp=read();
if(s[0]=='a')
{
v=read();
update_add(1,1,n);
}
else if(s[1]=='u')printf("%lld\n",query_sum(1,1,n));
else if(s[1]=='a')printf("%lld\n",query_max(1,1,n));
else if(s[1]=='i')printf("%lld\n",query_min(1,1,n));
else
{
v=read();
update_set(1,1,n);
}
}
}
int main()
{
n=read();Q=read();
build(1,1,n);
work();
return 0;
}