poj 2750 Potted Flower

poj 2750 Potted Flower

 

题意:给定一个环形序列,进行在线操作,每次修改一个元素,输出环上的最大连续子列的和,但不能是完全序列

分析:

如果不是环的话,只是一个序列,用线段树很方便求,所以将环从某一点切开成一个序列。

那么答案的最大连续和可能包含断点(换种想法,包含断点时的最大连续和即为 sum-区间最小的连续和)

1,若是所有的数都大于0,那么最大连续和(必须断开一个)即为 总和sum-最小非空连续和。

2,若是区间最小连续和小于0,那么答案就是MAX(区间最大连续和,sum-最小非空连续和)。即分为包含断点和不包含的比较。

 

View Code
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 
  8 #define ls rt<<1
  9 #define rs rt<<1|1 
 10 #define lson l,m,ls
 11 #define rson m+1,r,rs
 12 #define mid (l+r)>>1
 13 
 14 #define MAX(x,y) ((x)>(y)?(x):(y))
 15 #define MIN(x,y) ((x)>(y)?(y):(x))
 16 #define MAXN 100010
 17 
 18 int N,M;
 19 int a[MAXN];
 20 
 21 struct seg_tree
 22 {
 23     int l,r;
 24     int lmax,rmax,summax;
 25     int lmin,rmin,summin;
 26     int sum;
 27 };
 28 
 29 seg_tree tree[MAXN<<2];
 30 
 31 void PushUp(int rt)
 32 {
 33     tree[rt].sum=tree[ls].sum+tree[rs].sum;
 34 
 35     tree[rt].lmax=MAX(tree[ls].lmax,tree[ls].sum+tree[rs].lmax);
 36     tree[rt].rmax=MAX(tree[rs].rmax,tree[rs].sum+tree[ls].rmax);
 37     tree[rt].summax=MAX(MAX(tree[ls].summax,tree[rs].summax),tree[ls].rmax+tree[rs].lmax);
 38 
 39     
 40     tree[rt].lmin=MIN(tree[ls].lmin,tree[ls].sum+tree[rs].lmin);
 41     tree[rt].rmin=MIN(tree[rs].rmin,tree[rs].sum+tree[ls].rmin);
 42     tree[rt].summin=MIN(MIN(tree[ls].summin,tree[rs].summin),tree[ls].rmin+tree[rs].lmin);
 43 
 44 }
 45 
 46 void build(int l,int r,int rt)
 47 {
 48     if(l>r) return;
 49     tree[rt].l=l;
 50     tree[rt].r=r;
 51     if(l==r) 
 52     {
 53         tree[rt].sum=a[l];
 54         tree[rt].lmax=tree[rt].rmax=tree[rt].summax=a[l];
 55         tree[rt].lmin=tree[rt].rmin=tree[rt].summin=a[l];
 56         return;
 57     }
 58     int m=mid;
 59     build(lson);
 60     build(rson);
 61     PushUp(rt);
 62 }
 63 
 64 void update(int pos,int val,int rt)
 65 {
 66     if(tree[rt].l==tree[rt].r && tree[rt].l==pos)
 67     {
 68         tree[rt].sum=val;
 69         tree[rt].lmax=tree[rt].rmax=tree[rt].summax=val;
 70         tree[rt].lmin=tree[rt].rmin=tree[rt].summin=val;
 71         return;
 72     }
 73 
 74     int m=(tree[rt].l + tree[rt].r)>>1;
 75     if(pos<=m)
 76         update(pos,val,ls);
 77     else
 78         update(pos,val,rs);
 79     PushUp(rt);
 80 }
 81 
 82 int main()
 83 {
 84     while(scanf("%d",&N)!=EOF)
 85     {
 86         for(int i=1;i<=N;i++)
 87             scanf("%d",&a[i]);
 88         build(1,N,1);
 89 
 90         scanf("%d",&M);
 91         int pos,val;
 92 
 93         while(M--)
 94         {
 95             scanf("%d%d",&pos,&val);
 96             update(pos,val,1);
 97 
 98             if(tree[1].sum==tree[1].summax)
 99                 printf("%d\n",tree[1].sum-tree[1].summin);
100             else
101                 printf("%d\n",MAX(tree[1].summax,tree[1].sum-tree[1].summin));
102         }
103     }
104     return 0;
105 }

 

 

posted @ 2012-08-27 20:10  Missa  阅读(487)  评论(0编辑  收藏  举报