POJ - 2750 Potted Flower(线段树的区间合并)

点我看题

题意:给你一个环,实时更新环上某个结点的值,让你找出连续和的最大值(不能包括所有数)

分析:线段树的区间合并

参考代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>

using namespace std;
#define ls rt<<1
#define rs rt<<1|1
const int maxn = 1e6+5;
int n,m;
int val[maxn];
struct Node{
	int l,r;
	int sum;
	int lmax,rmax,maxsum;
	int lmin,rmin,minsum;
};
Node st[maxn<<2];

void PushUp( int rt)
{
	st[rt].sum = st[ls].sum+st[rs].sum;

	st[rt].lmax = max(st[ls].lmax,st[ls].sum+st[rs].lmax);
	st[rt].rmax = max(st[ls].rmax+st[rs].sum,st[rs].rmax);
	st[rt].maxsum = max(max(st[ls].maxsum,st[rs].maxsum),st[ls].rmax+st[rs].lmax);

	st[rt].lmin = min(st[ls].lmin,st[ls].sum+st[rs].lmin);
	st[rt].rmin = min(st[ls].rmin+st[rs].sum,st[rs].rmin);
	st[rt].minsum = min(min(st[ls].minsum,st[rs].minsum),st[ls].rmin+st[rs].lmin);
}

void Build( int l, int r, int rt)
{
	st[rt].l = l;
	st[rt].r = r;
	if( l == r)
	{
		st[rt].sum = val[l];
		st[rt].lmax = st[rt].rmax = st[rt].maxsum = val[l];
		st[rt].lmin = st[rt].rmin = st[rt].minsum = val[l];
		return;
	}
	
	int mid = (l+r)>>1;
	Build(l,mid,ls);
	Build(mid+1,r,rs);
	PushUp(rt);
}

void Update( int rt, int pos, int val)
{
	if( st[rt].l == st[rt].r && st[rt].l == pos)
	{
		st[rt].sum = val;
		st[rt].lmax = st[rt].rmax = st[rt].maxsum = val;
		st[rt].lmin = st[rt].rmin = st[rt].minsum = val;
		return;
	}

	int mid = (st[rt].l+st[rt].r)>>1;
	if( pos <= mid)
		Update(ls,pos,val);
	else
		Update(rs,pos,val);
	PushUp(rt);
}

int query()
{
	if( st[1].sum == st[1].maxsum)
		return st[1].sum-st[1].minsum;
	else
		return max(st[1].maxsum,st[1].sum-st[1].minsum);
}

int main()
{
	while( ~scanf("%d",&n))
	{
		for( int i = 1; i <= n; i++)
			scanf("%d",&val[i]);
		Build( 1,n,1);
		
		scanf("%d",&m);
		while( m--)
		{
			int pos,num;
			scanf("%d%d",&pos,&num);
			Update(1,pos,num);
			printf("%d\n",query());
		}
	}

	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值