#include<cstdio>
#include<algorithm>
using namespace std;
#define lc (o<<1)
#define rc (o<<1|1)
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
const int N=5e5+10;
const int INF=0x3fffffff;
struct tree{
int l,r,sum,dat,lmax,rmax;
}tr[N<<2];
int num[N];
//区间和sum,区间最大连续子段和dat,
//紧靠左端的最大连续子段和lmax
//紧靠右端的最大连续子段和rmax
int n,m,x,y,k;
inline void Init(tree &a,int val)
{
a.sum=a.dat=a.lmax=a.rmax=val;
}
inline void push_up(int o)
{
tr[o].sum=tr[lc].sum+tr[rc].sum;
tr[o].lmax=max(tr[lc].lmax,tr[lc].sum+tr[rc].lmax);
tr[o].rmax=max(tr[rc].rmax,tr[rc].sum+tr[lc].rmax);
tr[o].dat=max(max(tr[lc].dat,tr[rc].dat),tr[lc].rmax+tr[rc].lmax);
}
inline void build(int o,int l,int r)
{
tr[o].l=l;tr[o].r=r;
int mid=l+r>>1;
Init(tr[o],num[l]);
if(l==r)return;
build(lc,l,mid);build(rc,mid+1,r);
push_up(o);
}
inline void update(int o)
{
if(tr[o].l==tr[o].r){Init(tr[o],y);return;}
int mid=tr[o].l+tr[o].r>>1;
if(x<=mid)update(lc);
else update(rc);
push_up(o);
}
inline tree query(int o)
{
if(x<=tr[o].l&&tr[o].r<=y)return tr[o];
tree a,b,c;
int mid=tr[o].l+tr[o].r>>1;
Init(a,-INF);Init(b,-INF);
c.sum=0;
if(x<=mid)a=query(lc),c.sum+=a.sum;
if(y>mid)b=query(rc),c.sum+=b.sum;
c.dat=max(max(a.dat,b.dat),a.rmax+b.lmax);
c.lmax=max(a.lmax,b.lmax+a.sum);
if(x>mid)c.lmax=max(c.lmax,b.lmax);
c.rmax=max(b.rmax,b.sum+a.rmax);
if(y<=mid)c.rmax=max(c.rmax,a.rmax);
return c;
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
_rep(i,1,n)scanf("%d",&num[i]);
build(1,1,n);
_rep(i,1,m)
{
scanf("%d%d%d",&k,&x,&y);
if(k&1)
{
if(x>y)swap(x,y);
printf("%d\n",query(1).dat);
}
else update(1);
}
return 0;
}
【题解】CH4301 线段树
猜你喜欢
转载自blog.csdn.net/qq_41958841/article/details/82313312
今日推荐
周排行