线段树日常操作。
维护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 }