题目链接
题意
n
n
n 个数
m
m
m 次操作,输入格式
k
,
x
,
y
k,x,y
k,x,y
k
=
0
k = 0
k=0 表示修改第
x
x
x 数为
y
y
y
k
=
1
k = 1
k=1 表示查询
x
x
x 到
y
y
y 直接最大子段和
思路
线段树维护每个区间四个值
当前区间总和
当前区间靠左端连续的最大值
当前区间靠右端连续的最大值
当前区间的答案
pushup和query函数见代码
代码
#include <bits/stdc++.h>
using namespace std;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
struct Node
{
int lmax, rmax, sum, ans;
}t[(500000 << 2)+5];
void pushup(int rt)
{
t[rt].sum = t[rt<<1].sum+t[rt<<1|1].sum;
t[rt].lmax = max(t[rt<<1].lmax, t[rt<<1].sum+t[rt<<1|1].lmax);
t[rt].rmax = max(t[rt<<1|1].rmax, t[rt<<1|1].sum+t[rt<<1].rmax);
t[rt].ans = max(t[rt<<1].ans, max(t[rt<<1|1].ans, t[rt<<1].rmax+t[rt<<1|1].lmax));
}
void build(int rt, int l, int r)
{
if(l == r)
{
scanf("%d",&t[rt].ans);
t[rt].lmax = t[rt].rmax = t[rt].sum = t[rt].ans;
return;
}
int mid = (l+r) >> 1;
if(l <= mid) build(lson);
if(r > mid) build(rson);
pushup(rt);
}
void updata(int rt, int l, int r, int pos, int num)
{
if(l == r)
{
t[rt].lmax = t[rt].rmax = t[rt].sum = t[rt].ans = num;
return;
}
int mid = (l+r) >> 1;
if(pos <= mid) updata(lson,pos,num);
if(pos > mid) updata(rson,pos,num);
pushup(rt);
}
Node query(int rt, int l, int r, int ql, int qr)
{
if(ql <= l && r <= qr) return t[rt];
int mid = (l+r) >> 1;
if(qr <= mid) return query(lson,ql,qr);
if(ql > mid) return query(rson,ql,qr);
Node tl = query(lson,ql,qr), tr = query(rson,ql,qr), tmp;
tmp.sum = tl.sum+tr.sum;
tmp.lmax = max(tl.lmax, tl.sum+tr.lmax);
tmp.rmax = max(tr.rmax, tr.sum+tl.rmax);
tmp.ans = max(tl.rmax+tr.lmax, max(tl.ans, tr.ans));
return tmp;
}
int main()
{
int n, m;
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
while(m--)
{
int k, x, y;
scanf("%d%d%d",&k,&x,&y);
if(k) printf("%d\n",query(1,1,n,min(x,y),max(x,y)).ans);
else updata(1,1,n,x,y);
}
return 0;
}