题意:给定一个环形的序列,值可正可负,求最大的连续子序列。(每次更新都需要输出结果,最多包含N-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; }