zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    HDU1883 Phone Cell
    HDU2297 Run
    关于反射的疑惑
    struts2+spring 实例教程
    在.Net 模板页中使用CSS样式
    到底是什么反射,泛型,委托,泛型
    asp.net如何实现删除文件夹及文件内容操作
    学好C#方法
    Web网页安全色谱
    总结一些ASP.NET常用代码
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6760604.html
Copyright © 2011-2022 走看看