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 }

 

 

你可能感兴趣的:(poj)