题目大意:给定一个由花盆做成的圈,并且给定每个花盆的价值,做一个长椅,使得长椅旁边的所有的花盆的价值和是最大的,并且这个长椅不能在所有的花盆的中间,求最大!
分析:题目中数据过大,所以只能采用线段树进行操作,可以将围成一个圈拆成一个线段,题中每个花盆的价值有正有有负,如果所以都为正的话那么最大值就为所有的和减去某个花盆最小的值,如果有负的话,那么最大值就为总和减去最小的或者最大的连续的和!
经验:当需要维护大区间的某个量,其中小区间会不断更新。则可以将整个区间建成线段树,
从而在logn时间内完成更新。
Sample Input
5
3 -2 1 2 -5
4
2 -2
5 -5
2 -4
5 -1
Sample Output
4
4
3
5
/**
[线段树] poj 2750 Potted Flower
题意:N个数组成一个环,动态更新环上某个数的值,询问整个环上最大的连续子段和
(不能包括整个环)
整个区间的最大值 == 区间和时,max = sum - minn;
否则,max = max(maxx,sum - minn);
此题关键是树上要维护较多数据,具体见pushUp函数
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 100001
#define L(i) i << 1
#define R(i) i << 1 | 1
struct _st
{
int l,r;
int sum,minn,maxx,lmin,lmax,rmin,rmax;
int mid()
{
return (l + r) >> 1;
}
}st[N<<2];
int a[N];
void pushUp(int id)
{
int l = L(id), r = R(id);
st[id].sum = st[l].sum + st[r].sum;
st[id].lmin = min(st[l].lmin,st[l].sum + st[r].lmin);
st[id].rmin = min(st[r].rmin,st[l].rmin + st[r].sum);
st[id].lmax = max(st[l].lmax,st[l].sum + st[r].lmax);
st[id].rmax = max(st[r].rmax,st[l].rmax + st[r].sum);
st[id].minn = min(st[l].minn,st[r].minn);
st[id].minn = min(st[id].minn,st[l].rmin + st[r].lmin);
st[id].maxx = max(st[l].maxx,st[r].maxx);
st[id].maxx = max(st[id].maxx,st[l].rmax + st[r].lmax);
}
void build(int id,int l,int r)
{
st[id].l = l;
st[id].r = r;
if(l == r)
{
st[id].sum = st[id].minn = st[id].maxx
= st[id].lmax = st[id].lmin = st[id].rmax = st[id].rmin = a[l];
return ;
}
int mid = st[id].mid();
build(L(id),l,mid);
build(R(id),mid+1, r);
pushUp(id);
}
int query()
{
if(st[1].sum == st[1].maxx)
return st[1].sum - st[1].minn;
return max(st[1].maxx,st[1].sum - st[1].minn);
}
void update(int id,int p,int v)
{
if(st[id].l == st[id].r)
{
st[id].sum = st[id].minn = st[id].maxx
= st[id].lmax = st[id].lmin = st[id].rmax = st[id].rmin = v;
return ;
}
int mid = st[id].mid();
if(mid >= p)
update(L(id),p,v);
else
update(R(id),p,v);
pushUp(id);
}
int main()
{
int n,i,m,va;
scanf("%d",&n);
for(i = 1; i <= n; ++i)
scanf("%d", a + i);
build(1,1,n);
scanf("%d",&m);
while(m --)
{
scanf("%d%d",&i,&va);
update(1,i,va);
printf("%d\n",query());
}
return 0;
}