您的位置:首页 > 其它

POJ_2750_Potted Flower_线段树

2014-09-22 12:05 344 查看
还有一周就十一了啊,七天没网的生活即将到来。。。。。

题意:

有一个长为n的环,每个位置有一个整数值,可能为正可能为负,在线单点更新某些点的值,每次更新要求输出最大连续和,且不能是整个环,保证每次的答案都是正数。

Input
There will be a single test data in the input. You are given an integer N (4 <= N <= 100000) in the first input line.

The second line contains N integers, which are the initial attractive value of each potted flower. The i-th number is for the potted flower on the i-th position.

A single integer M (4 <= M <= 100000) in the third input line, and the following M lines each contains an instruction "A B" in the form described above.

Restriction: All the attractive values are within [-1000, 1000]. We guarantee the maximal sum will be always a positive integer.

Output
For each instruction, output a single line with the maximum sum of attractive values for the optimum cane-chair.
虽说线段树的代码写了好多遍了,也写过一些线段树的题,但是这个题一开始还是不会做。。。。。

其实不难,对每个树上的点记录当前的最大连续和、最小连续和(由于环形的原因需要)、和、最小值、从左右端点开始的最大最小连续和(这四个量都是为了更新最大连续和和最小连续和,为了把两个区间从断点连起来)。

ans=max(maxsum[1],sum[1]-minsum[1]);

感觉这个题出题还是有一丢丢问题,保证结果为正数就是这个问题,可能是因为所有元素都为负数的原因吧。为了避免把整个环都取了,需要注意判断是否存在负数,如果存在则肯定会避免那个负数,如果没有负数则要注意不能算上maxsum[1],因为它会记录整个环都算上的情况。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
#define mxn 100010
int n;
int a[mxn<<1];
int ll[mxn<<2],rr[mxn<<2];
bool neg[mxn<<2];
int sum[mxn<<2],maxsum[mxn<<2],minsum[mxn<<2],minn[mxn<<2];
int lmaxs[mxn<<2],rmaxs[mxn<<2],lmins[mxn<<2],rmins[mxn<<2];
void eq(int loc,int id){
if(a[loc]<0)	neg[id]=true;
else	neg[id]=false;
minn[id]=a[loc];
sum[id]=maxsum[id]=minsum[id]=lmaxs[id]=rmaxs[id]=a[loc];
lmins[id]=rmins[id]=a[loc];
}
void up(int ls,int rs,int id){
neg[id]=neg[ls]|neg[rs];
minn[id]=min(minn[ls],minn[rs]);
sum[id]=sum[ls]+sum[rs];
maxsum[id]=max(max(maxsum[ls],maxsum[rs]),rmaxs[ls]+lmaxs[rs]);
minsum[id]=min(min(minsum[ls],minsum[rs]),rmins[ls]+lmins[rs]);
lmaxs[id]=max(lmaxs[ls],sum[ls]+lmaxs[rs]);
rmaxs[id]=max(rmaxs[rs],sum[rs]+rmaxs[ls]);
lmins[id]=min(lmins[ls],sum[ls]+lmins[rs]);
rmins[id]=min(rmins[rs],sum[rs]+rmins[ls]);
}
void build(int l,int r,int id){
ll[id]=l,rr[id]=r;
if(l==r){
eq(l,id);
return;
}
int m=(l+r)>>1,ls=id<<1,rs=ls|1;
build(l,m,ls);
build(m+1,r,rs);
up(ls,rs,id);
}
void update(int loc,int x,int id){
if(ll[id]==rr[id]){
a[loc]=x;
eq(loc,id);
return;
}
int m=(ll[id]+rr[id])>>1,ls=id<<1,rs=ls|1;
if(loc<=m)	update(loc,x,ls);
else	update(loc,x,rs);
up(ls,rs,id);
}
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;++i)	scanf("%d",&a[i]);
build(0,n-1,1);
int m;
scanf("%d",&m);
int A,B,ans;
for(int M=0;M<m;++M){
scanf("%d%d",&A,&B);
update(A-1,B,1);
ans=sum[1]-minsum[1];
if(neg[1])	ans=max(maxsum[1],ans);
printf("%d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: