CST2018 3-1-1 Sum (15%)

简单的线段树,单点修改,区间求和。

很简单。

 

CST2018 3-1-2 Max (20%)

高级的线段树。

维护区间最大和,区间和,左边最大和,右边最大和。

单点修改的时候一路吧区间都改了就好了。

求子段最大值也就判断一下左右就好了。

略微复杂。

  1 #include <cstdio>
  2 
  3 using namespace std;
  4 const int N = 5e5 + 5;
  5 const int inf = 1e9;
  6 int n, m;
  7 int a[N];
  8 
  9 inline int max(int x, int y) {
 10     return x > y ? x : y;
 11 }
 12 
 13 struct seg {
 14     seg *ls, *rs;
 15     int sum, mx, mxl, mxr;
 16     
 17     void* operator new(size_t) {
 18         static seg* c;
 19         c = new seg[1];
 20         c -> ls = c -> rs = NULL;
 21         c -> mxl = c -> mxr = c -> mx = c -> sum = 0;
 22         return c;
 23     }
 24     
 25     inline void change_point(int x) { //change the value of a single point
 26         if (x > 0) {
 27             sum = mx = mxl = mxr = x;
 28         } else {
 29             sum = x;
 30             mx = mxl = mxr = 0;
 31         }
 32     }
 33     
 34     inline void update() {
 35         if (ls == NULL || rs == NULL) return;
 36         sum = ls -> sum + rs -> sum;
 37         mx = max(max(ls -> mx, rs -> mx), ls -> mxr + rs -> mxl);
 38         mxl = max(ls -> mxl, ls -> sum + rs -> mxl);
 39         mxr = max(rs -> mxr, rs -> sum + ls -> mxr);
 40     }
 41     
 42     #define mid (l + r >> 1)
 43     void build(int l, int r) {
 44         if (l == r) {
 45             change_point(a[l]);
 46             return;
 47         }
 48         ls = new()seg, ls -> build(l, mid);
 49         rs = new()seg, rs -> build(mid + 1, r);
 50         update();
 51     }
 52     
 53     void modify(int l, int r, int pos, int x) {
 54         if (pos < l || r < pos) return;
 55         if (l == r) {
 56             change_point(x);
 57             return;
 58         }
 59         if (pos <= mid) ls -> modify(l, mid, pos, x);
 60         if (mid < pos) rs -> modify(mid + 1 , r, pos, x);
 61         update();
 62     }
 63     
 64     seg* query(int l, int r, int L, int R) {
 65         seg* ret = new()seg;
 66         if (l == L && R == r) {
 67             *ret = *this;
 68             return ret;
 69         }
 70         if (R <= mid) return ls -> query(l, mid, L, R);
 71         if (L > mid) return rs -> query(mid + 1, r, L, R);
 72         
 73         ret -> ls = ls -> query(l, mid, L, mid);
 74         ret -> rs = rs -> query(mid + 1, r, mid + 1, R);
 75         ret -> update();
 76         delete ret -> ls;
 77         delete ret -> rs;
 78         return ret;
 79     }
 80     #undef mid
 81 } *segment, *ans;
 82 
 83 int main() {
 84     int op, x, y;
 85     scanf("%d%d", &n, &m);
 86     for (int i = 1; i <= n; ++i)
 87         scanf("%d", a + i);
 88     segment = new()seg;
 89     segment -> build(1, n);    
 90     for (int i = 1; i <= m; ++i) {
 91         scanf("%d%d%d", &op, &x, &y);
 92         if (op == 0) {
 93             segment -> modify(1, n, x, y);
 94         } else {
 95             ans = segment -> query(1, n, x, y);
 96             printf("%d\n", ans -> mx);
 97             delete ans;
 98         }
 99     }
100     return 0;
101 }
View Code

相关文章: