HDU 4348 To the moon 主席树成段更新

来源:互联网 发布:地图染色堆栈算法 编辑:程序博客网 时间:2024/06/08 00:20
对于成段更新,以前都是访问到懒惰标记的节点然后向下更新,这次学了一个新的方法,遇到懒惰节点不向下更新,而是从根节点开始累加所有的标记值。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef __int64 LL;const int maxn = 200010;int ls[maxn*20], rs[maxn*20];LL sum[maxn*20], add[maxn*20];int T[maxn], tot;int num[maxn], a[maxn], n, q;struct node{    char ch;    int l, r, h;}b[maxn];void pushup(int rt){    sum[rt] = sum[ls[rt]]+sum[rs[rt]];}void build(int l, int r, int& rt){rt = ++tot;sum[rt] = 0;add[rt] = 0;if(l == r)    {        scanf("%I64d", &sum[rt]);        ls[rt] = rs[rt] = 0;        return;    }int m = (l+r)>>1;build(l, m, ls[rt]);build(m+1, r, rs[rt]);pushup(rt);}void update(int last, int x, int y, int l, int r, int& rt, LL d){rt = ++tot;ls[rt] = ls[last];rs[rt] = rs[last];add[rt] = add[last];sum[rt] = sum[last]+1LL*(y-x+1)*d;if(l == x && r == y)    {        add[rt] += d;        return;    }int m = (l+r)>>1;if(y <= m)update(ls[last], x, y, l, m, ls[rt], d);else if(x > m)update(rs[last], x, y, m+1, r, rs[rt], d);    else    {        update(ls[last], x, m, l, m, ls[rt], d);        update(rs[last], m+1, y, m+1, r, rs[rt], d);    }}LL query(int x, int y, int l, int r, int rt){    LL ans = 1LL*(y-x+1)*add[rt];if(l == x && y == r)return sum[rt];int m = (l+r)>>1;if(y <= m)ans += query(x, y, l, m, ls[rt]);else if(x > m)ans += query(x, y, m+1, r, rs[rt]);    else    {        ans += query(x, m, l, m, ls[rt]);        ans += query(m+1, y, m+1, r, rs[rt]);    }    return ans;}void cal(){    tot = 0;    build(1, n, T[0]);    int now = 0;    while(q--)    {        char s[10];        scanf("%s", s);        if(s[0] == 'C')        {            int l, r;            LL d;            scanf("%d %d %I64d", &l, &r, &d);            update(T[now], l, r, 1, n, T[now+1], d);            now++;        }        else if(s[0] == 'Q')        {            int l, r;            scanf("%d %d", &l, &r);            LL ans = query(l, r, 1, n, T[now]);            printf("%I64d\n", ans);        }        else if(s[0] == 'H')        {            int l, r, t;            scanf("%d %d %d", &l, &r, &t);            LL ans = query(l, r, 1, n, T[t]);            printf("%I64d\n", ans);        }        else        {            int t;            scanf("%d", &t);            now = t;        }    }}int main(){while(scanf("%d %d", &n, &q) != EOF){cal();}return 0;}
0 0