和上回做的线段树几乎一样。
http://blog.youkuaiyun.com/johsnows/article/details/62237377
不过这回只能有单点更新的方法去做了
代码:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=5e4+5;
const int inf=10000;
struct p
{
LL lmax;
LL rmax;
LL max;
LL sum;
void init()
{
sum=0;
lmax=rmax=max=-inf;
return;
}
void maintan(p a, p b)
{
sum=a.sum+b.sum;
lmax=a.lmax>(a.sum+b.lmax)?a.lmax:(a.sum+b.lmax);
rmax=b.rmax>(b.sum+a.rmax)?b.rmax:(b.sum+a.rmax);
max=a.max>b.max?a.max:b.max;
max=max>(a.rmax+b.lmax)?max:(a.rmax+b.lmax);
return;
}
}seg[maxn<<4];
void update (int e, int l, int r, int ll, int x)
{
// printf("%d %d\n", l, r);
if(l==r && r==ll)
{
seg[e].sum=seg[e].max=seg[e].lmax=seg[e].rmax=x;
// printf("update%d %d %lld\n", l, r, seg[e].max);
return;
}
int mid=(l+r)/2;
if(ll<=mid)update(e<<1, l, mid, ll, x);
else update(e<<1|1, mid+1, r, ll, x);
seg[e].maintan(seg[e<<1], seg[e<<1|1]);
return;
}
p query(int e, int l, int r, int ll, int rr)
{
// printf("%d %d\n", l, r);
p res;
res.init();
if(ll<=l && r<=rr)
{
return seg[e];
}
int mid=(l+r)/2;
if(ll<=mid)res.maintan(query(e<<1, l, mid, ll, rr), res);
// printf("a %d %d %lld\n", l, r, res.max);
if(rr>mid)res.maintan(res, query(e<<1|1, mid+1, r, ll, rr));
// printf("b %d %d %lld\n", l, r, res.max);
return res;
}
int main()
{
int n;
cin>>n;
int i, j, x;
for(i=1; i<=n; i++)
{
scanf("%d", &x);
update(1, 1, n, i, x);
}
// for(i=1; i<=n; i++)printf("%lld\n", seg[i].max);
int m,y,z;
cin>>m;
for(i=0; i<m; i++)
{
scanf("%d%d%d", &x, &y, &z);
if(x==0)
{
update(1, 1, n, y, z);
}
else
{
p ans;
ans=query(1, 1, n, y, z);
printf("%lld\n", ans.max);
}
}
}