给个关注啥的都行一个小时啥也没看出来QAQ
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+10;
struct node{
ll maxx;
ll tag1,tag2;
ll l,r;//测试用
bool if_cov;
}segtree[4*maxn];
ll n,m,a[maxn];
void print()
{
for(int i=1;i<=4*n-1;i++)
{
printf("%d~%d:%d\n",segtree[i].l,segtree[i].r,segtree[i].maxx);//测试用
}
printf("\n\n");
}
void push_up(ll p)
{
segtree[p].maxx=max(segtree[p<<1].maxx,segtree[p<<1|1].maxx);
}
void push_down(ll p)
{
if(!segtree[p].if_cov)//只有区间加,正常下传标记
{
segtree[p<<1].tag1+=segtree[p].tag1;
segtree[p<<1|1].tag1+=segtree[p].tag1;//加法标记+
segtree[p<<1].maxx+=segtree[p].tag1;
segtree[p<<1|1].maxx+=segtree[p].tag1;//最大值加上所加的值
}
else//有区间修改
{
segtree[p<<1].tag1=segtree[p].tag1;
segtree[p<<1|1].tag1=segtree[p].tag1;//加法标记直接传
segtree[p<<1|1].tag2=segtree[p].tag2;
segtree[p<<1].tag2=segtree[p].tag2;//覆盖标记也直接传
segtree[p<<1].if_cov=1;segtree[p<<1|1].if_cov=1;//覆盖操作传递
segtree[p<<1].maxx=segtree[p].tag1+segtree[p].tag2;
segtree[p<<1].maxx=segtree[p].tag1+segtree[p].tag2;//既然有覆盖操作那么就不考虑历史值,只能是覆盖值加上加法标记
}
segtree[p].if_cov=segtree[p].tag1=segtree[p].tag2=0;//下传完毕清空该节点信息
}
void build(ll l,ll r,ll p)
{
segtree[p].l=l,segtree[p].r=r;
segtree[p].maxx=-1e18;//初始最小值
if(l==r)
{
segtree[p].maxx=a[l];
return ;
}
ll mid=(l+r)>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
push_up(p);
}
void change(ll n1,ll n2,ll l,ll r,ll p,ll k)
{
if(n1<=l&&r<=n2)
{
segtree[p].maxx=k;
segtree[p].tag1=0;//硬性修改,加法标记用不到了
segtree[p].tag2=k;
segtree[p].if_cov=1;
return ;
}
push_down(p);
ll mid=(l+r)>>1;
if(n1<=mid) change(n1,n2,l,mid,p<<1,k);
if(n2>mid) change(n1,n2,mid+1,r,p<<1|1,k);
push_up(p);
}
void modify(ll n1,ll n2,ll l,ll r,ll p,ll k)
{
if(n1<=l&&r<=n2)
{
segtree[p].maxx+=k;
segtree[p].tag1+=k;
return ;
}
push_down(p);
ll mid=(l+r)>>1;
if(n1<=mid) modify(n1,n2,l,mid,p<<1,k);
if(n2>mid) modify(n1,n2,mid+1,r,p<<1|1,k);
push_up(p);
}
ll query(ll n1,ll n2,ll l,ll r,ll p)
{
//printf("query n1 %lld,n2 %lld,l:%lld,r:%lld\n",n1,n2,l,r);
if(n1<=l&&r<=n2)
{
return segtree[p].maxx;
}
ll res=-1e18;
push_down(p);
ll mid=(l+r)>>1;
if(n1<=mid) res=max(res,query(n1,n2,l,mid,p<<1));
if(n2>mid) res=max(res,query(n1,n2,mid+1,r,p<<1|1));
return res;
}
int main()
{
// freopen("1.in","r",stdin);
// freopen("2.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1,n,1);
while(m--)
{
ll a1,a2,a3,a4;
scanf("%lld%lld%lld",&a1,&a2,&a3);
if(a1==1)
{
scanf("%lld",&a4);
change(a2,a3,1,n,1,a4);
// print();
}
else if(a1==2)
{
scanf("%lld",&a4);
modify(a2,a3,1,n,1,a4);
// print();
}
else
{
printf("%lld\n",query(a2,a3,1,n,1));
// print();
}
}
return 0;
}
感激不尽