SPOJ TO THE MOON 主席树(有动态修改)
来源:互联网 发布:达内 训机构北京php 编辑:程序博客网 时间:2024/06/05 11:12
题目大意:
题目大意:给定一些数字,有以下几个操作
a、[L,R]区间的数字变化D的数值。并且时间向前推进
b、询问某个时间的[L,R]区间的数字之和,这不花费时间
c、回到X时间。
主席树带动态操作裸题。 但是也可以用主席树,不push版本
AC CODE: 300+M内存使用
#include <bits/stdc++.h>using namespace std;#define pr(x)x#define prln(x)x//#define pr(x)cout<< #x << " = " <<x<<" "//#define prln(x)cout<< #x << " = " <<x<<endlconst int maxn = 123456;const int maxnode = maxn * 100;int n, m;struct node { int lson, rson; long long val;//区间权重 long long change;//区间修改值,为0表示没有需要传递的 int ver;}tree[maxnode]; int tail, root[maxn]; long long w[maxn];char inp[15];int ql, qr, qans, qver; #define LSON tree[o].lson,L, M #define RSON tree[o].rson, M + 1 , R #define SELF o,L,R #define lc tree[o].lson #define rc tree[o].rson void push_down(int o, int L, int R)//向下传递标记, o节点的val值不变{ if (tree[o].change && L < R) { if (tree[lc].ver != qver){tree[++tail] = tree[lc];tree[o].lson = tail;tree[lc].ver = qver;}if (tree[rc].ver != qver){tree[++tail] = tree[rc];tree[o].rson = tail;tree[rc].ver = qver;}tree[lc].change += tree[o].change; tree[rc].change += tree[o].change; tree[o].change = 0; } } //更新o节点的val信息。那么就需要把儿子的信息汇总到o//要特别注意,儿子的懒人标记的信息和val信息汇总void maintain(int o, int L, int R) { if (L < R) { int M = L+(R-L)/2; tree[o].val = tree[lc].val + tree[rc].val + tree[lc].change * (M-L+1) + tree[rc].change * (R-M); } //L==R的情况,不包含的左右儿子,所以再query里询问到的节点,直接结合处理了} void build(int o, int L, int R) { tree[o].change = 0; tree[o].ver = 0;//一开始建树,建的是0号版本的if (L== R) { tree[o].val = w[L]; return ; } tree[o].lson = ++ tail; tree[o].rson = ++ tail; int M = L + (R - L) / 2; build(LSON); build(RSON); maintain(SELF);}void insert(int &o, int L, int R){tree[++ tail] = tree[o];o = tail;tree[o].ver = qver;if (ql <= L && R <= qr){tree[o].change += qans;return;}push_down(SELF);int M = L + (R-L)/2;if (ql <= M)insert(LSON);else maintain(LSON);if (qr > M)insert(RSON);else maintain(RSON);maintain(SELF);}long long query(int o, int L, int R) { if (tree[o].ver != qver){tree[++tail] = tree[o];o = tail;tree[o].ver = qver;}if (ql <= L && R <= qr) { //返回的值需要考虑到懒人标记信息return tree[o].val + tree[o].change * (R-L+1);//因为根节点的传递标记一直都在 } push_down(SELF); int M = L + (R - L) / 2; long long ret = 0; if (ql <= M) ret += query(LSON); else maintain(LSON); if (qr > M) ret += query(RSON); else maintain(RSON); maintain(SELF); return ret; } void init(){for (int i = 1; i <=n; ++ i)scanf("%lld", &w[i]);//读入一些数据root[0] = 0;tail = 0;build(root[0], 1, n);}void doit(){int now =0;while (m--){scanf("%s", inp);if (inp[0] == 'C')//区间更新,now+1{++now;root[now] = root[now - 1];qver = now;scanf("%d%d%d", &ql, &qr, &qans);//ql,qr区间变化qansinsert(root[now], 1, n);}if (inp[0]=='Q')//询问当前{scanf("%d%d", &ql, &qr);qver = now;printf("%lld\n",query(root[now], 1, n));}if (inp[0]=='H')//询问que时间的L,R区间和{scanf("%d%d%d", &ql, &qr, &qver);printf("%lld\n",query(root[qver], 1, n));}if (inp[0] == 'B')//回到过去{scanf("%d", &now);}}puts("");}int main(){while (~scanf("%d%d", &n, &m)){init();doit();}return 0;}
0 0
- SPOJ TO THE MOON 主席树(有动态修改)
- vjudge: spoj--to the moon(主席树区间修改)
- SPOJ TTM To the moon(主席树+区间操作)
- HDU 4348 / SPOJ TTM To the moon [主席树]
- SPOJ TTMTo the moon(主席树)
- HDU 4348 To the moon 【主席树+区间修改】
- HDU 4348 To the moon [主席树 区间修改]
- 【HDU4348】To The Moon-主席树(可持久化线段树)区间修改+区间询问
- SPOJ TTM To The Moon 主席树的区间更新与查询
- HDU 4348 To the moon(主席树区间更新)
- HDU-4348 To the moon(主席树)
- hdu 4348 To the moon (主席树)
- HDU-4348 To the moon (主席树)
- spoj TTM To the moon
- hdu4348 To the moon(区间修改,区间查询的主席树)
- hdu4348 To the moon (主席树 || 离线线段树)
- hdu-4348-To the moon-主席树在线区间更新
- HDU 4348To the moon 主席树 + 区间更新
- 角标选择排序
- hdu 5701 中位数计数
- 97. Interleaving String
- 对于学习排序法的总结
- 【BZOJ 2761】[JLOI2011]不重复数字
- SPOJ TO THE MOON 主席树(有动态修改)
- 常用类
- Linux TCP协议使用进程实现并发服务器
- codeforces 725G. Messages on a Tree
- 【UML】构件图(Component Diagram)
- c++ 进制转换,字母大小写转换,map按值排序 简单函数
- 数据结构实验之数组一:矩阵转置
- The NTLM Authentication Protocol
- 使用ListIterator 对List遍历时修改,删除