ncwzdlsd @ 2023-03-10 10:18:46
有 swap
,查询修改貌似也没有问题,样例可过,交上去就
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=5e5+5;
int a[maxn];
struct node
{
int ls,rs,ml,mr,ans,sum;
// maxleft,maxright,maxvalue,最大子段和,区间和
}t[maxn];
void merge(int k)//合并区间统计答案
{
t[k].sum=t[k*2].sum+t[k*2+1].sum;
t[k].ml=max(t[k*2].ml,t[k*2].sum+t[k*2+1].mr);//左区间最大子段和、左区间和+右区间左区间最大子段和
t[k].mr=max(t[k*2+1].mr,t[k*2].ml+t[k*2+1].sum);
t[k].ans=max(max(t[k*2].ans,t[k*2+1].ans),t[k*2].mr+t[k*2+1].ml/*横跨左右区间*/);
}
void build(int k,int l,int r)
{
t[k].ls=l;t[k].rs=r;
if(l==r) {t[k].sum=t[k].ml=t[k].mr=t[k].ans=a[l];return;}
int mid=(l+r)/2;
build(k*2,l,mid);build(k*2+1,mid+1,r);
merge(k);
}
//OK
void change(int k,int x,int y)
{
if(t[k].ls==t[k].rs) {t[k].ml=t[k].mr=t[k].ans=t[k].sum=y;return;}
int mid=(t[k].ls+t[k].rs)/2;
if(x<=mid) change(k*2,x,y);
else change(k*2+1,x,y);
merge(k);//值改变,重新合并
}
node query(int k,int l,int r)
{
if(l<=t[k].ls&&r>=t[k].rs) return t[k];
int mid=(t[k].ls+t[k].rs)/2;
if(r<=mid) return query(k*2,l,r);//只在左区间
else if(l>mid) return query(k*2+1,l,r);//只在右区间
else
{
node aa=query(k*2,l,r),bb=query(k*2+1,l,r),nw/*合并操作*/;
nw.sum=aa.sum+bb.sum;
nw.ml=max(aa.ml,aa.sum+bb.ml);
nw.mr=max(bb.mr,bb.sum+aa.mr);
nw.ans=max(max(aa.ans,bb.ans),aa.mr+bb.ml);
return nw;
}
}
signed main()
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(m--)
{
int k;cin>>k;
if(k==1)
{
int a,b;cin>>a>>b;
if(a>b) swap(a,b);
cout<<query(1,a,b).ans<<endl;
}
else
{
int p,s;cin>>p>>s;
change(1,p,s);
}
}
return 0;
}
by ncwzdlsd @ 2023-03-10 10:22:19
merge
手残写错了,此帖结