POJ

来源:互联网 发布:网络共享电脑打不开 编辑:程序博客网 时间:2024/06/14 01:38

点我看题

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

分析:线段树的区间合并

参考代码:

#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>using namespace std;#define ls rt<<1#define rs rt<<1|1const 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);elseUpdate(rs,pos,val);PushUp(rt);}int query(){if( st[1].sum == st[1].maxsum)return st[1].sum-st[1].minsum;elsereturn 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;}