• 洛谷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代码
  • 相关阅读:
    linux /dev 常见特殊设备介绍与应用[loop,null,zero,full,random]
    由web程序出现乱码开始挖掘(Bom头、字符集与乱码)
    linux shell命令快捷获得系统帮助(一)[manpages定义规范]
    定期分割tomcat输出文件 catalina.out
    readyState的五种状态
    C# FileSystemWatcher
    不用第三个变量实现a,b的值交换
    我的eWork,我能赚钱的SOHO空间
    如何网上炒股
    没有为扩展名“.html”注册的生成提供程序
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/9354525.html
Copyright © 2020-2023  润新知