洛谷P4513 小白逛公园

线段树日常操作。

维护left,right,sum,large表示左右最大,总和,区间最大。

然后瞎搞搞就OK了。

pushup l == r 的时候 left right large 都等于 sum

查询的时候分类讨论力度要大...

由于只有单点修改所以没有标记,比较爽。

洛谷的数据,记得把输入的两个数比较,可能要swap

  1 #include <cstdio>
  2 #include <algorithm>
  3 
  4 const int N = 500010, INF = 0x3f3f3f3f;
  5 
  6 struct SegmentTree {
  7     int large[N << 2], left[N << 2], right[N << 2], sum[N << 2];
  8 
  9     inline void pushup(int l, int r, int o) {
 10         if(l == r) {
 11             large[o] = sum[o];
 12             //left[o] = right[o] = std::max(sum[o], 0);
 13             left[o] = right[o] = sum[o];
 14             return;
 15         }
 16         int ls = o << 1;
 17         int rs = ls | 1;
 18         sum[o] = sum[ls] + sum[rs];
 19         large[o] = std::max(large[ls], large[rs]);
 20         large[o] = std::max(large[o], left[rs] + right[ls]);
 21         left[o] = std::max(left[ls], sum[ls] + left[rs]);
 22         right[o] = std::max(right[rs], sum[rs] + right[ls]);
 23         return;
 24     }
 25 
 26     void change(int p, int l, int r, int o, int v) {
 27         if(l == r) {
 28             sum[o] = v;
 29             pushup(l, r, o);
 30             return;
 31         }
 32         int mid = (l + r) >> 1;
 33         if(p <= mid) {
 34             change(p, l, mid, o << 1, v);
 35         }
 36         else {
 37             change(p, mid + 1, r, o << 1 | 1, v);
 38         }
 39         pushup(l, r, o);
 40         return;
 41     }
 42     int getsum(int L, int R, int l, int r, int o) {
 43         if(L <= l && r <= R) {
 44             return sum[o];
 45         }
 46         if(r < L || R < l) {
 47             return 0;
 48         }
 49         int mid = (l + r) >> 1;
 50         return getsum(L, R, l, mid, o << 1) + getsum(L, R, mid + 1, r, o << 1 | 1);
 51     }
 52     void ask(int L, int R, int l, int r, int o, int &ans, int &la, int &ra) {
 53         if(L <= l && r <= R) {
 54             ans = large[o];
 55             la = left[o];
 56             ra = right[o];
 57             return;
 58         }
 59         int mid = (l + r) >> 1;
 60         if(R <= mid) {
 61             ask(L, R, l, mid, o << 1, ans, la, ra);
 62             return;
 63         }
 64         if(mid < L) {
 65             ask(L, R, mid + 1, r, o << 1 | 1, ans, la, ra);
 66             return;
 67         }
 68         int A = -INF;
 69         int B = A, C = A, D = A, E = A, F = A;
 70         ask(L, R, l, mid, o << 1, A, B, C);
 71         ask(L, R, mid + 1, r, o << 1 | 1, D, E, F);
 72         ans = std::max(A, D);
 73         ans = std::max(ans, C + E);
 74         if(L <= l) {
 75             la = std::max(B, sum[o << 1] + E);
 76         }
 77         else {
 78             la = std::max(B, E + getsum(L, mid, l, mid, o << 1));
 79         }
 80         if(R >= mid) {
 81             ra = std::max(F, sum[o << 1 | 1] + C);
 82         }
 83         else {
 84             ra = std::max(F, C + getsum(mid + 1, R, mid + 1, r, o << 1 | 1));
 85         }
 86         return;
 87     }
 88     void build(int l, int r, int o) {
 89         if(l == r) {
 90             scanf("%d", &sum[o]);
 91             pushup(l, r, o);
 92             return;
 93         }
 94         int mid = (l + r) >> 1;
 95         build(l, mid, o << 1);
 96         build(mid + 1, r, o << 1 | 1);
 97         pushup(l, r, o);
 98         return;
 99     }
100 }SgT;
101 
102 int main() {
103     int n, m;
104     scanf("%d%d", &n, &m);
105     SgT.build(1, n, 1);
106     int f, x, y;
107     while(m--) {
108         scanf("%d%d%d", &f, &x, &y);
109         if(f == 1) {
110             if(x > y) {
111                 std::swap(x, y);
112             }
113             int A, B, C;
114             SgT.ask(x, y, 1, n, 1, A, B, C);
115             printf("%d
", A);
116         }
117         else {
118             SgT.change(x, 1, n, 1, y);
119         }
120     }
121     return 0;
122 }
AC代码
原文地址:https://www.cnblogs.com/huyufeifei/p/9354525.html