和I相比有了单点更新,所以不能只记录一个前缀和,而是要在线段树上多维护一个sum,表示这个结点的区间和,然后其他的就和I一样了。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 50001;
int a[N];
struct Node 
{
	int l, r, sum;
	int maxl, maxr, maxn;
} node[N << 2];
void pushup( int i )
{
	int lc = i << 1, rc = lc | 1;
	node[i].sum = node[lc].sum + node[rc].sum;
	node[i].maxl = max( node[lc].maxl, node[lc].sum + node[rc].maxl );
	node[i].maxr = max( node[rc].maxr, node[rc].sum + node[lc].maxr );
	node[i].maxn = max( node[lc].maxn, node[rc].maxn );
	node[i].maxn = max( node[i].maxn, node[lc].maxr + node[rc].maxl );
}
void build( int i, int l, int r )
{
	node[i].l = l, node[i].r = r;
	if ( l == r )
	{
		node[i].sum = node[i].maxl = node[i].maxr = node[i].maxn = a[l];
		return ;
	}
	int lc = i << 1, rc = lc | 1, mid = ( l + r ) >> 1;
	build( lc, l, mid );
	build( rc, mid + 1, r );
	pushup(i);
}
void update( int i, int pos, int val )
{
	if ( node[i].l == pos && node[i].r == pos )
	{
		node[i].sum = node[i].maxl = node[i].maxr = node[i].maxn = val;
		return ;
	}
	int mid = ( node[i].l + node[i].r ) >> 1;
	if ( pos <= mid )
	{
		update( i << 1, pos, val );
	}
	else
	{
		update( i << 1 | 1, pos, val );
	}
	pushup(i);
}
Node query( int i, int l, int r )
{
	if ( node[i].l == l && node[i].r == r )
	{
		return node[i];
	}
	int lc = i << 1, rc = lc | 1, mid = ( node[i].l + node[i].r ) >> 1;
	if ( r <= mid )
	{
		return query( lc, l, r );
	}
	else if ( l > mid )
	{
		return query( rc, l, r );
	}
	else
	{
		Node ln = query( lc, l, mid ), rn = query( rc, mid + 1, r ), res;
		res.sum = ln.sum + rn.sum;
		res.maxl = max( ln.maxl, ln.sum + rn.maxl );
		res.maxr = max( rn.maxr, rn.sum + ln.maxr );
		res.maxn = max( ln.maxn, rn.maxn );
		res.maxn = max( res.maxn, ln.maxr + rn.maxl );
		return res;
	}
}
int main ()
{
	int n, m;	
	while ( scanf("%d", &n) != EOF )
	{
		for ( int i = 1; i <= n; i++ )
		{
			scanf("%d", a + i);
		}
		build( 1, 1, n );
		scanf("%d", &m);
		while ( m-- )
		{
			int op, x, y;
			scanf("%d%d%d", &op, &x, &y);
			if ( op == 0 )
			{
				update( 1, x, y );
			}
			else
			{
				Node tmp = query( 1, x, y );
				printf("%d\n", tmp.maxn);
			}
		}
	}
	return 0;
}
spoj 1716 Can you answer these queries III(线段树)
原文:http://www.cnblogs.com/huoxiayu/p/4691141.html