#include<bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
#define inf 1e18
#define int long long
using namespace std;
int n,q;
int a[100005];
struct tree
{
int l,r,tag1,tag2,tag3;
int mx,hmx;
}c[100005*4];
void push_up(int p)
{
c[p].mx=max(c[ls].mx,c[rs].mx);
c[p].hmx=max(c[ls].hmx,c[rs].hmx);
}
void build(int p,int l,int r)
{
c[p].l=l,c[p].r=r;
c[p].tag3=-inf;
if(l==r)
{
c[p].mx=c[p].hmx=a[l];
return;
}
int mid=c[p].l+c[p].r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
push_up(p);
}
void push_down(int p)
{
if(c[p].tag3!=-inf)
{
c[ls].hmx=max(c[ls].hmx,c[p].tag3+c[p].tag2);
c[rs].hmx=max(c[rs].hmx,c[p].tag3+c[p].tag2);
c[ls].mx=c[rs].mx=c[p].tag3+c[p].tag1;
c[ls].tag1=c[rs].tag1=c[p].tag1;
c[ls].tag2=max(c[ls].tag2,c[p].tag2);
c[rs].tag2=max(c[rs].tag2,c[p].tag2);
c[ls].tag3=c[rs].tag3=c[p].tag3;
c[p].tag1=c[p].tag2=0,c[p].tag3=-inf;
}
else
{
c[ls].hmx=max(c[ls].hmx,c[p].tag2+c[ls].mx);
c[rs].hmx=max(c[rs].hmx,c[p].tag2+c[rs].mx);
c[ls].mx+=c[p].tag1,c[rs].mx+=c[p].tag1;
c[ls].tag2=max(c[ls].tag2,c[ls].tag1+c[p].tag2),c[rs].tag2=max(c[rs].tag2,c[rs].tag1+c[p].tag2);
c[ls].tag1+=c[p].tag1,c[rs].tag1+=c[p].tag1;
c[p].tag1=c[p].tag2=0;
}
}
int query1(int p,int l,int r)
{
if(l<=c[p].l&&c[p].r<=r)return c[p].mx;
push_down(p);
int mid=c[p].l+c[p].r>>1,val=-inf;
if(l<=mid)val=max(val,query1(ls,l,r));
if(r>mid)val=max(val,query1(rs,l,r));
return val;
}
int query2(int p,int l,int r)
{
if(l<=c[p].l&&c[p].r<=r)return c[p].hmx;
push_down(p);
int mid=c[p].l+c[p].r>>1,val=-inf;
if(l<=mid)val=max(val,query2(ls,l,r));
if(r>mid)val=max(val,query2(rs,l,r));
return val;
}
void change1(int p,int l,int r,int val)
{
if(l<=c[p].l&&c[p].r<=r)
{
c[p].tag1+=val;
c[p].tag2=max(c[p].tag2,c[p].tag1);
c[p].mx+=val;
c[p].hmx=max(c[p].mx,c[p].hmx);
return;
}
push_down(p);
int mid=c[p].l+c[p].r>>1;
if(l<=mid)change1(ls,l,r,val);
if(r>mid)change1(rs,l,r,val);
push_up(p);
}
void change2(int p,int l,int r,int val)
{
if(c[p].l!=c[p].r)push_down(p);
if(l<=c[p].l&&c[p].r<=r)
{
c[p].tag1=c[p].tag2=0;
c[p].mx=c[p].tag3=val;
c[p].hmx=max(c[p].mx,c[p].hmx);
return;
}
int mid=c[p].l+c[p].r>>1;
if(l<=mid)change2(ls,l,r,val);
if(r>mid)change2(rs,l,r,val);
push_up(p);
}
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",a+i);
build(1,1,n);
scanf("%lld",&q);
for(int i=1;i<=q;i++)
{
char opt;
scanf(" %c",&opt);
if(opt=='Q')
{
int l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",query1(1,l,r));
}
else if(opt=='A')
{
int l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",query2(1,l,r));
}
else if(opt=='P')
{
int l,r,val;
scanf("%lld%lld%lld",&l,&r,&val);
change1(1,l,r,val);
}
else
{
int l,r,val;
scanf("%lld%lld%lld",&l,&r,&val);
change2(1,l,r,val);
}
}
return 0;
}
如上是我自己写的此题代码。写完后我发现我做法似乎和普遍做法有点区别。我的做法只有3个tag。我感觉我的做法没问题,但无法完全保证,求dalao看看有没有问题。
我的三个tag分别是,当前+的tag,历史最大+的tag,当前赋值的tag,如果为-inf则无值。