• [HDU4348]To the moon(主席树)


    传送门

    对于这个题,显然要打lazy标记了,但是lazy标记pushdown的时候肯定会增加一大堆节点,然后就MLE了。(题解这么说的,我其实不会pushdown)

    所以,就换另一种方式,把标记直接打到当前区间,把当前区间的父亲节点大小都更新。求区间和的时候把沿途的标记都加起来就可以了。

    注意分多钟情况。

    ——代码

     1 #include <cstdio>
     2 #define ls son[now][0], l, mid
     3 #define rs son[now][1], mid + 1, r
     4 #define LL long long
     5 
     6 using namespace std;
     7 
     8 const int N = 5000005;
     9 
    10 int n, m, tot;
    11 int rt[N], son[N][2], add[N];
    12 LL sum[N];
    13 
    14 inline void pushup(int now)
    15 {
    16     sum[now] = sum[son[now][0]] + sum[son[now][1]];
    17 }
    18 
    19 inline void build(int &now, int l, int r)
    20 {
    21     now = ++tot;
    22     add[now] = 0;
    23     if(l == r)
    24     {
    25         scanf("%lld", &sum[now]);
    26         return;
    27     }
    28     int mid = (l + r) >> 1;
    29     build(ls);
    30     build(rs);
    31     pushup(now);
    32 }
    33 
    34 inline void update(int &now, int l, int r, int last, int ql, int qr, int x)
    35 {
    36     now = ++tot;
    37     add[now] = add[last];
    38     sum[now] = sum[last];
    39     son[now][0] = son[last][0];
    40     son[now][1] = son[last][1];
    41     sum[now] += (LL)x * (qr - ql + 1);
    42     if(l == ql && r == qr)
    43     {
    44         add[now] += x;
    45         return;
    46     }
    47     int mid = (l + r) >> 1;
    48     if(qr <= mid) update(ls, son[now][0], ql, qr, x);
    49     else if(ql > mid) update(rs, son[now][1], ql, qr, x);
    50     else
    51     {
    52         update(ls, son[now][0], ql, mid, x);
    53         update(rs, son[now][1], mid + 1, qr, x);
    54     }
    55 }
    56 
    57 inline LL query(int now, int l, int r, int ql, int qr)
    58 {
    59     if(l == ql && r == qr) return sum[now];
    60     int mid = (l + r) >> 1;
    61     LL ret = (LL)add[now] * (qr - ql + 1);
    62     if(qr <= mid) return ret + query(ls, ql, qr);
    63     else if(ql > mid) return ret + query(rs, ql, qr);
    64     else return ret + query(ls, ql, mid) + query(rs, mid + 1, qr);
    65 }
    66 
    67 int main()
    68 {
    69     int i, x, y, z, now;
    70     bool f = 0;
    71     char s[5];
    72     while(~scanf("%d %d", &n, &m))
    73     {
    74         if(f) printf("
    ");
    75         else f = 1;
    76         now = tot = 0;
    77         build(rt[0], 1, n);
    78         for(i = 1; i <= m; i++)
    79         {
    80             scanf("%s", s);
    81             switch(s[0])
    82             {
    83                 case 'C': scanf("%d %d %d", &x, &y, &z); now++; update(rt[now], 1, n, rt[now - 1], x, y, z); break;
    84                 case 'Q': scanf("%d %d", &x, &y); printf("%lld
    ", query(rt[now], 1, n, x, y)); break;
    85                 case 'H': scanf("%d %d %d", &x, &y, &z); printf("%lld
    ", query(rt[z], 1, n, x, y)); break;
    86                 case 'B': scanf("%d", &now); break;
    87             }
    88         }
    89     }
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    前端分页功能的实现以及原理
    Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
    Jquery实现的几款漂亮的时间轴
    jQuery点击弹出层,弹出模态框,点击模态框消失
    如何用CSS快速布局(一)—— 布局元素详细
    验证控件jQuery Validation Engine调用外部函数验证
    Javascript实现页面跳转的几种方式
    最详细win7下手动搭建PHP环境:apache2.4.23+php7.0.11
    spark调优——JVM调优
    spark调优——Shuffle调优
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6760604.html
Copyright © 2020-2023  润新知