poj 2750 Potted Flower(线段树#8)

来源:互联网 发布:mysql创建一个学生表 编辑:程序博客网 时间:2024/05/21 17:58

这个题关键是这一段代码

struct node{        int l, r;        int lmaxs, rmaxs, maxsum;        int lmins, rmins, minsum;         int max, min;         int sum; }Tree[N * 4];

分别表示左起连续最大值,右起连续最大值,最大连续值,以及对应的最小值。还有是最大数,最小数,sum表示区间和。

全为正和全为负的情况,正则取sum - min, 负则取max;

其他情况,最大连续值要么在区间内,要么跨过n。前者好考虑,如果是后者,那么没包含的区间一定是最小连续区间。

为什么呢?这样证明:首先这个区间两端均为负数且区间和为负数,这个很显然,如果有另外一个区间sum比它还小(显然为负),那么最大连续区间完全可以舍弃那个区间而将它包含进来。这样便得证。

代码704ms

#include <cstdio>#include <cstdlib>#include <algorithm> #define L(t) t << 1#define R(t) t << 1 | 1 #define N 100010using namespace std;int array[N]; int poscnt, negcnt; struct node{        int l, r;        int lmaxs, rmaxs, maxsum;        int lmins, rmins, minsum;         int max, min;         int sum; }Tree[N * 4];void update_sum(int x){        if (Tree[x].l == Tree[x].r)return;         Tree[x].sum = Tree[L(x)].sum + Tree[R(x)].sum;        Tree[x].lmins = min(Tree[L(x)].lmins, Tree[L(x)].sum + Tree[R(x)].lmins);         Tree[x].rmins = min(Tree[R(x)].rmins, Tree[R(x)].sum + Tree[L(x)].rmins) ;        Tree[x].lmaxs = max(Tree[L(x)].lmaxs, Tree[L(x)].sum + Tree[R(x)].lmaxs);        Tree[x].rmaxs = max(Tree[R(x)].rmaxs, Tree[R(x)].sum + Tree[L(x)].rmaxs);        Tree[x].maxsum = max(max(Tree[L(x)].maxsum, Tree[R(x)].maxsum), Tree[L(x)].rmaxs + Tree[R(x)].lmaxs);        Tree[x].minsum = min(min(Tree[L(x)].minsum, Tree[R(x)].minsum), Tree[L(x)].rmins + Tree[R(x)].lmins);        Tree[x].min = min(Tree[L(x)].min, Tree[R(x)].min);        Tree[x].max = max(Tree[L(x)].max, Tree[R(x)].max);         } void build(int l, int r, int x) {        Tree[x].l = l;        Tree[x].r = r;        if (l == r)        {               Tree[x].maxsum = Tree[x].minsum = Tree[x].sum = array[l];               Tree[x].lmaxs = Tree[x].rmaxs = Tree[x].sum;               Tree[x].lmins = Tree[x].rmins = Tree[x].sum;               Tree[x].max = Tree[x].min = Tree[x].sum;                return;         }         int mid = (l + r) /2;        build(l, mid, L(x));        build(mid + 1, r, R(x));        update_sum(x);         } void update(int nu, int val, int x){       if (Tree[x].l == Tree[x].r)       {               if (Tree[x].sum >= 0 && val < 0)poscnt--, negcnt++;               else if (Tree[x].sum < 0 && val >= 0)poscnt++, negcnt--;                Tree[x].maxsum = Tree[x].minsum = Tree[x].sum = val;               Tree[x].lmaxs = Tree[x].rmaxs = Tree[x].sum;               Tree[x].lmins = Tree[x].rmins = Tree[x].sum;               Tree[x].max = Tree[x].min = Tree[x].sum;                return;       }       int mid = (Tree[x].l + Tree[x].r) /2;       if (nu <= mid)       {              update(nu, val, L(x));              update_sum(L(x));       }       else       {              update(nu, val, R(x));              update_sum(R(x));       }       update_sum(x); } int main(){      // FILE* fp = fopen("in.txt", "r");       int n, m;        scanf(  "%d", &n);       poscnt = negcnt = 0;        for (int i = 1; i <= n; i++)       {             scanf( "%d", array + i);            if (array[i] < 0)negcnt++;            else poscnt++;       }        scanf( "%d", &m);        build(1, n, 1);        int a, b;        while (m--)       {             scanf( "%d %d", &a, &b);             update(a, b, 1);             int ans;               if (poscnt == n)ans = Tree[1].sum - Tree[1].min;              else if (poscnt == 0)ans = Tree[1].max;               else              {                    ans = max(Tree[1].maxsum, Tree[1].sum - Tree[1].minsum);              }                             printf("%d\n", ans);       }       //getchar();       return 0;} 


原创粉丝点击