题目大意:
求区间最大子区间的和。
思路分析:
记录左最大,右最大,区间最大。
注意Q_L 和 Q_R 就好。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 55555
using namespace std;
int lef[maxn<<2];
int rig[maxn<<2];
int tre[maxn<<2];
int sum[maxn<<2];
void pushup(int num)
{
sum[num]=sum[num<<1]+sum[num<<1|1];
lef[num]=max(lef[num<<1],sum[num<<1]+lef[num<<1|1]);
rig[num]=max(rig[num<<1|1],sum[num<<1|1]+rig[num<<1]);
tre[num]=max(max(tre[num<<1],tre[num<<1|1]),rig[num<<1]+lef[num<<1|1]);
}
void build(int num,int s,int e)
{
if(s==e)
{
scanf("%d",&tre[num]);
sum[num]=rig[num]=lef[num]=tre[num];
return ;
}
int mid=(s+e)>>1;
build(lson);
build(rson);
pushup(num);
}
int Q_L(int num,int s,int e,int l,int r)
{
if(l<=s && r>=e)
{
return lef[num];
}
int mid=(s+e)>>1;
if(r<=mid)return Q_L(lson,l,r);
else if(l>mid)return Q_L(rson,l,r);
else
{
return max(lef[num<<1],max(sum[num<<1],sum[num<<1]+Q_L(rson,mid+1,r)));
}
}
int Q_R(int num,int s,int e,int l,int r)
{
if(l<=s && r>=e)
{
return rig[num];
}
int mid=(s+e)>>1;
if(r<=mid)return Q_R(lson,l,r);
else if(l>mid)return Q_R(rson,l,r);
else
{
return max(rig[num<<1|1],max(sum[num<<1|1],sum[num<<1|1]+Q_R(lson,l,mid)));
}
}
int query(int num,int s,int e,int l,int r)
{
if(l<=s && r>=e)
{
return tre[num];
}
int mid=(s+e)>>1;
if(r<=mid)return query(lson,l,r);
else if(l>mid)return query(rson,l,r);
else
{
return max(Q_R(lson,l,mid)+Q_L(rson,mid+1,r),max(query(lson,l,mid),query(rson,mid+1,r)));
}
}
void update(int num,int s,int e,int pos,int val)
{
if(s==e)
{
sum[num]=tre[num]=lef[num]=rig[num]=val;
return;
}
int mid=(s+e)>>1;
if(pos<=mid)update(lson,pos,val);
else update(rson,pos,val);
pushup(num);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
build(1,1,n);
int m;
scanf("%d",&m);
while(m--)
{
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op)
printf("%d\n",query(1,1,n,l,r));
else update(1,1,n,l,r);
}
}
return 0;
}