caek @ 2020-01-19 19:30:14
#include <bits/stdc++.h>
using namespace std;
long long t,n,m,a[50000000];
struct tree{
int l,r;//左右儿子编号
int lmax,rmax,mx,sum;
}f[60000000];
void pushup(int i)//更新操作
{
f[i].lmax=max(f[i<<i].lmax,f[i<<1].sum+f[i<<1|1].lmax);
f[i].rmax=max(f[i<<i].rmax,f[i<<1].sum+f[i<<1|1].rmax);
f[i].mx=max(f[i<<1].mx,max(f[i<<1|1].mx,f[i<<1].rmax+f[i<<1|1].lmax));
f[i].sum=f[i<<1].sum+f[i<<1|1].sum;
}
void update(int i,int v)//i节点的值用v更新
{
f[i].sum=f[i].lmax=f[i].rmax=f[i].mx=v;
return;
}
void build(int i,int left,int right)//建树 i结点的范围是left到right
{
f[i].l=left;
f[i].r=right;
if (left==right)
{
f[i].lmax=a[left];
f[i].rmax=a[left];
f[i].sum=a[left];
f[i].mx=a[left];
return;
}
int mid=(left+right)/2;
build(i<<1,left,mid);//i<<1==i*2
build(i<<1|1,mid+1,right);//i<<1|1==i*2+1
pushup(i);
}
tree querymax(int i,int left,int right)
{
if (f[i].l==left&&f[i].r==right)
return f[i];
int mid=(f[i].l+f[i].r)/2;
if (right<=mid) return querymax(i<<1,left,right);
else if (mid<left) return querymax(i<<1|1,left,right);
else
{
tree lson=querymax(i<<1,left,mid);
tree rson=querymax(i<<1|1,mid+1,right);
tree root;
root.lmax=max(lson.lmax,lson.sum+rson.lmax);
root.rmax=max(lson.rmax,lson.sum+rson.rmax);
root.mx=max(lson.mx,max(rson.mx,lson.rmax+rson.lmax));
root.sum=lson.sum+rson.sum;
return root;
}
}
void add(int i,int left,int right,int v)
{
if (f[i].l==left&&f[i].r==right)
{
update(i,v);
return;
}
int mid=(f[i].l+f[i].r)/2;
if (right<=mid) add(i<<1,left,right,v);
else if (mid<left) add(i<<1|1,left,right,v);
pushup(i);
}
int main()
{
cin>>n>>m;
for (int i=1; i<=n; i++)
cin>>a[i];
build(1,1,n);
for (int i=1; i<=m; i++)
{
long long op,l,r,v,k;
cin>>op;
if (op==1)
{
cin>>l>>r;
tree ans=querymax(1,min(l,r),max(l,r));
cout<<ans.mx<<endl;
}
if (op==2)
{
cin>>k>>v;
add(1,k,k,v);
}
}
return 0;
}
by DepletedPrism @ 2020-01-19 23:47:03
@caek RE 不只是数组越界啊喂
返回的两个 querymax
最后两参好像传错了 = =
tree querymax(int i,int left,int right)
{
if (f[i].l==left&&f[i].r==right)
return f[i];
int mid=(f[i].l+f[i].r)/2;
if (right<=mid) return querymax(i<<1,left,right);
else if (mid<left) return querymax(i<<1|1,left,right);