【SPOJ】2916 Can you answer these queries V

操作:

给出x属于[x1,y1],y属于[x2,y2],求[x,y]的最大连续和。

将区间分3段考虑,答案可能由某一段的最大连续和,或者某一段往左的最大连续和,某一段往右的最大连续和组合而来。需要特判的是,区间可能存在包含关系。

  1 #include<cstdio>
  2 #define MAX(a,b) ((a)>(b)?(a):(b))
  3 #define MAXN 10010
  4 #define oo 987654321
  5 struct node {
  6     int left, right, sum, val;
  7     void Init() {
  8         sum = 0;
  9         left = right = val = -oo;
 10     }
 11 };
 12 node tree[MAXN << 2];
 13 inline void PushUp(int rt) {
 14     tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
 15     tree[rt].left = MAX(tree[rt<<1].left,tree[rt<<1].sum+tree[rt<<1|1].left);
 16     tree[rt].right =
 17             MAX(tree[rt<<1|1].right,tree[rt<<1|1].sum+tree[rt<<1].right);
 18     tree[rt].val = MAX(tree[rt<<1].val,tree[rt<<1|1].val);
 19     tree[rt].val = MAX(tree[rt].val,tree[rt<<1].right+tree[rt<<1|1].left);
 20 }
 21 void Build(int L, int R, int rt) {
 22     if (L == R) {
 23         scanf("%d", &tree[rt].val);
 24         tree[rt].left = tree[rt].right = tree[rt].sum = tree[rt].val;
 25     } else {
 26         int mid = (L + R) >> 1;
 27         Build(L, mid, rt << 1);
 28         Build(mid + 1, R, rt << 1 | 1);
 29         PushUp(rt);
 30     }
 31 }
 32 node Query(int x, int y, int L, int R, int rt) {
 33     if (x <= L && R <= y)
 34         return tree[rt];
 35     int mid = (L + R) >> 1;
 36     node a, b, res;
 37     a.Init(), b.Init();
 38     if (x <= mid)
 39         a = Query(x, y, L, mid, rt << 1);
 40     if (y > mid)
 41         b = Query(x, y, mid + 1, R, rt << 1 | 1);
 42     res.left = MAX(a.left,a.sum+b.left);
 43     res.right = MAX(b.right,b.sum+a.right);
 44     res.sum = a.sum + b.sum;
 45     res.val = MAX(a.val,b.val);
 46     res.val = MAX(res.val,a.right+b.left);
 47     return res;
 48 }
 49 int main() {
 50     int c, n, q, ans, tmp1, tmp2, x1, y1, x2, y2;
 51     scanf("%d", &c);
 52     while (c--) {
 53         scanf("%d", &n);
 54         Build(1, n, 1);
 55         scanf("%d", &q);
 56         while (q--) {
 57             scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
 58             if (y1 <= x2) {
 59                 ans = 0;
 60                 tmp1 = tmp2 = -oo;
 61                 if (y1 + 1 <= x2 - 1)
 62                     ans += Query(y1 + 1, x2 - 1, 1, n, 1).sum;
 63                 if (y1 == x2) {
 64                     tmp1 = Query(x2, y2, 1, n, 1).left;
 65                     ans += tmp1;
 66                     if (x1 <= y1 - 1) {
 67                         tmp2 = Query(x1, y1 - 1, 1, n, 1).right;
 68                         ans += tmp2;
 69                     }
 70                     ans = MAX(ans,tmp1);
 71                     tmp2 = Query(x1, y1, 1, n, 1).right;
 72                     ans = MAX(ans,tmp2);
 73                 } else
 74                     ans += Query(x2, y2, 1, n, 1).left
 75                             + Query(x1, y1, 1, n, 1).right;
 76             } else {
 77                 ans = Query(x2, y1, 1, n, 1).val;
 78                 tmp1 = Query(y1, y2, 1, n, 1).left
 79                         + Query(x1, x2, 1, n, 1).right;
 80                 if (x2 + 1 <= y1 - 1)
 81                     tmp1 += Query(x2 + 1, y1 - 1, 1, n, 1).sum;
 82                 ans = MAX(ans,tmp1);
 83                 tmp1 = Query(x1, x2, 1, n, 1).right;
 84                 if (y1 >= x2)
 85                     ans = MAX(ans,tmp1);
 86                 if (x2 < y2)
 87                     tmp1 += Query(x2 + 1, y2, 1, n, 1).left;
 88                 ans = MAX(ans,tmp1);
 89                 tmp1 = Query(y1, y2, 1, n, 1).left;
 90                 if (x2 <= y1)
 91                     ans = MAX(ans,tmp1);
 92                 if (x1 < y1)
 93                     tmp1 += Query(x1, y1 - 1, 1, n, 1).right;
 94                 ans = MAX(ans,tmp1);
 95             }
 96             printf("%d\n", ans);
 97         }
 98     }
 99     return 0;
100 }
原文地址:https://www.cnblogs.com/DrunBee/p/2661856.html