POJ 2750 Potted Flower 线段树+DP

题意:给定一个环形的序列,值可正可负,求最大的连续子序列。(每次更新都需要输出结果,最多包含N-1个点)。

POJ 2750 Potted Flower 线段树+DP_第1张图片

#include <iostream>
using namespace std;

#define N 100005
int pot[N];

struct item
{
	int sum;
	int lmax,lmin;
	int rmax,rmin;
	int submax, submin;
	int left, right;
} node[N*6];

int max ( int a, int b )
{
	return ( a > b ? a : b );
}

int min ( int a, int b )
{
	return ( a < b ? a : b );
}

void update ( int root )
{
	int lchild = root * 2;
	int rchild = root * 2 + 1;
	node[root].sum = node[lchild].sum + node[rchild].sum;  
	node[root].lmax = max ( node[lchild].lmax, node[lchild].sum + node[rchild].lmax ); 
	node[root].lmin = min ( node[lchild].lmin, node[lchild].sum + node[rchild].lmin );  
	node[root].rmax = max ( node[rchild].rmax, node[lchild].rmax + node[rchild].sum );
	node[root].rmin = min ( node[rchild].rmin, node[lchild].rmin + node[rchild].sum );  
	node[root].submax = max ( max ( node[lchild].submax, node[rchild].submax ), node[lchild].rmax + node[rchild].lmax );  
	node[root].submin = min ( min ( node[lchild].submin, node[rchild].submin ), node[lchild].rmin + node[rchild].lmin ); 
}

void build_tree ( int l, int r, int root )
{
	node[root].left = l;
	node[root].right = r;
	if ( l == r )
	{
		node[root].sum = node[root].lmax = node[root].lmin = node[root].rmax = pot[l];
		node[root].rmin = node[root].submax = node[root].submin = pot[l];
		return;
	}
	
	int mid = ( l + r ) / 2;
	build_tree ( l, mid, root * 2 );
	build_tree ( mid + 1, r, root * 2 + 1 );
	update ( root );
}

void modify ( int pos, int val, int root )
{
	if ( node[root].left == node[root].right && node[root].left == pos )
	{
		node[root].sum = node[root].lmax = node[root].lmin = node[root].rmax = val;
		node[root].rmin = node[root].submax = node[root].submin = val;
		return;
	}
	int mid = ( node[root].left + node[root].right ) / 2;
	if ( pos <= mid )
		modify ( pos, val, root * 2 );
	else
		modify ( pos, val, root * 2 + 1 );
	update ( root );
}

int main()
{
	int n, m, pos, val, i;
	scanf("%d",&n);
	for ( i = 1; i <= n; ++i )
		scanf("%d",pot+i);
	build_tree ( 1, n, 1 );
	scanf("%d",&m);
	while ( m-- )
	{
		scanf("%d%d",&pos,&val);
		modify(pos,val,1);
		if ( node[1].sum == node[1].submax )
			printf("%d\n",node[1].sum - node[1].submin);
		else
			printf("%d\n", max ( node[1].sum - node[1].submin, node[1].submax ) );
	}
	return 0;
}


你可能感兴趣的:(POJ 2750 Potted Flower 线段树+DP)