BUPT2017 wintertraining(15) #8G

题意

给一个数组a,有n个数,m次操作。\(N, M ≤ 10^5, |A i| ≤ 10^9, 1 ≤ l ≤ r ≤ N, |d| ≤ 10^4\)

操作有四种,

C l r d:更新区间[l,r],值都加上d,并且时间前进1

Q l r:查询[l,r]的区间和

H l r t:查询t时刻的区间和

B t:回到t时刻(一定是历史时刻),且t时刻之后的操作都作废了。

题解

这道题的关键是怎么更新区间和。

本来线段树更新区间和要push down也就是把懒惰标记下移,但是这样,整个修改区间都需要新建线段树的节点,空间不够。

所以考虑在查询的时候传参数下去,也就是一路加上大区间的lazy值,这样就不用push down了。

代码

  1. #include <cstdio>
  2. #include <cstring>
  3. #define N 100005
  4. #define M (N*25)
  5. typedef long long ll;
  6. namespace PST{
  7. int T[N],lson[M],rson[M],tot,n;
  8. ll sum[M], lz[M];
  9. void init(int _n){
  10. tot=0;
  11. n=_n;
  12. memset(sum,0,sizeof sum);
  13. memset(lz,0,sizeof lz);
  14. }
  15. void push_up(int root,int l,int r){
  16. sum[root]=sum[lson[root]]+sum[rson[root]]+lz[root]*(r-l+1);
  17. }
  18. int build(int l,int r){
  19. int root=++tot;
  20. if(l==r){
  21. scanf("%lld",sum+tot);
  22. return tot;
  23. }
  24. int mid=l+r>>1;
  25. lson[root]=build(l,mid);
  26. rson[root]=build(mid+1,r);
  27. push_up(root,l,r);
  28. return root;
  29. }
  30. int update(int root,int l,int r,int L,int R,int val){
  31. int newroot=++tot;
  32. lson[newroot]=lson[root];
  33. rson[newroot]=rson[root];
  34. lz[newroot]=lz[root];
  35. if(L<=l&&r<=R){
  36. sum[newroot]=sum[root]+(ll)val*(r-l+1);
  37. lz[newroot]+=val;
  38. return newroot;
  39. }
  40. int mid=l+r>>1;
  41. if(L<=mid)
  42. lson[newroot]=update(lson[root],l,mid,L,R,val);
  43. if(R>mid)
  44. rson[newroot]=update(rson[root],mid+1,r,L,R,val);
  45. push_up(newroot,l,r);
  46. return newroot;
  47. }
  48. ll query(int root,int l,int r,int L,int R,ll add){
  49. if(L<=l&&r<=R){
  50. return sum[root]+(add)*(r-l+1);
  51. }
  52. int mid=l+r>>1;
  53. ll ans=0;
  54. if(L<=mid)
  55. ans+=query(lson[root],l,mid,L,R,lz[root]+add);
  56. if(R>mid)
  57. ans+=query(rson[root],mid+1,r,L,R,lz[root]+add);
  58. return ans;
  59. }
  60. }
  61. int main(){
  62. int n,m;
  63. while(~scanf("%d%d",&n,&m)){
  64. int now;
  65. PST::init(n);
  66. PST::T[now=0]=PST::build(1,n);
  67. for(int i=0;i<m;++i){
  68. char op;
  69. int l,r,t,d;
  70. scanf(" %c",&op);
  71. if(op=='Q'){
  72. scanf("%d%d",&l,&r);
  73. printf("%lld\n",PST::query(PST::T[now],1,n,l,r,PST::lz[PST::T[now]]));
  74. }else if(op=='H'){
  75. scanf("%d%d%d",&l,&r,&t);
  76. printf("%lld\n",PST::query(PST::T[t],1,n,l,r,PST::lz[PST::T[t]]));
  77. }else if(op=='B'){
  78. scanf("%d", &now);
  79. PST::tot=PST::T[now+1]-1;
  80. }else if(op=='C'){
  81. scanf("%d%d%d",&l,&r,&d);
  82. int tmp=now;
  83. PST::T[++now]=PST::update(PST::T[tmp],1,n,l,r,d);
  84. }
  85. }
  86. }
  87. }

【HDU - 4348】To the moon(主席树在线区间更新)的更多相关文章

  1. HDU 4348 To the moon 主席树 在线更新

    http://acm.hdu.edu.cn/showproblem.php?pid=4348 以前做的主席树没有做过在线修改的题做一下(主席树这种东西正经用法难道不是在线修改吗),标记永久化比较方便. ...

  2. hdu 4348 To the moon (主席树)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4348 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q ...

  3. hdu 4348 To the moon (主席树区间更新)

    传送门 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q l r:查询当前时间戳区间[l,r]中所有数的和 . (3)H ...

  4. HDU 4348 To the moon 主席树

    题意: 给出一个长度为\(n(n \leq 10^5)\)的序列,最开始时间\(t=0\),支持下面几个操作: \(C \, l \, r \, d\):将区间\([l,r]\)每个数都加上\(d\) ...

  5. hdu 4348 To the moon 主席树区间更新

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Prob ...

  6. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  7. HDU 2665 Kth number(主席树静态区间第K大)题解

    题意:问你区间第k大是谁 思路:主席树就是可持久化线段树,他是由多个历史版本的权值线段树(不是普通线段树)组成的. 具体可以看q学姐的B站视频 代码: #include<cmath> #i ...

  8. hdu 3397 Sequence operation(线段树:区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...

  9. HDU4348To the moon主席树,区间修改

    题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q l r:查询当前时间戳区间[l,r]中所有数的和 . (3)H l r ...

随机推荐

  1. C#跨进程读取listview控件中的数据

    http://www.cnblogs.com/Charltsing/p/slv32.html 欢迎交流:QQ564955427 读取标准的32位listview控件中的数据,网上已经有很多代码了.今天 ...

  2. jconsole & jvisualvm远程监视websphere服务器JVM的配置案

    jconsole是JDK里自带的一个工具,可以监测Java程序运行时所有对象的申请.释放等动作,将内存管理的所有信息进行统计.分析.可视化.我们可以根据这些信息判断程序是否有内存泄漏问题. 使用jco ...

  3. Shell脚本1

    1Shell编程 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell脚本 Shell 脚本(shell scr ...

  4. vim 永久添加行号

    sudo vi /etc/vim/vimrc 打开vimrc文件,最下面添加set nu,保存就可以添加行号了,set autoindent是自动换行

  5. TCP 握手和挥手图解(有限状态机)

    1.引言 TCP 这段看过好几遍,老是记不住,没办法找工作涉及到网络编程这块,各种问 TCP .今天好好整理一下握手和挥手过程.献给跟我一样忙碌,找工作的童鞋,欢迎大神批评指正. 2.TCP 的连接建 ...

  6. API接口TOKEN设计

    首先需要知道API是什么?   API(Application Programming Interface)即应用程序接口.你可以认为 API 是一个软件组件或是一个 Web 服务与外界进行的交互的接 ...

  7. [编程笔记]第二章 C语言预备知识

    /*第二讲 C语言预备专业知识 1.CPU 内存条 硬盘 显卡 主板 显示器之间的关系 CPU不能直接处理硬盘上的数据 文件存储在硬盘,当运行时,操作系统把硬盘上的数据调用到内存条上. 图像以数据的形 ...

  8. 谷歌浏览器报错 Active resource loading counts reached to a per-frame

    Active resource loading counts reached to a per-frame limit while the tab is in background. Network ...

  9. vue+webpack项目打包后背景图片加载不出来问题解决

    在做VUE +的WebPack脚手架项目打包完成后,在IIS服务器上运行发现项目中的背景图片加载不出来检查项目代码发现是因为CSS文件中,背景图片引用的路径问题;后来通过修改配置文件,问题终于解决了, ...

  10. rbac组件引用

    一. 批量操作思路 # 待新增 路由系统中有,但是数据库中还没有 路由系统的集合 - 数据库中权限集合 # 待更新 路由系统中有,数据库中也有, 只是更改了一些信息 路由系统的集合 & 数据库 ...