链接: http://acm.hdu.edu.cn/showproblem.php?pid=4348

题意:

4种操作:

C l r c   区间[l,r]加c,时间+1

Q l r    询问当前时间区间[l,r]的和

H l  r c  询问在时间t时,区间[l,r]的和

B x  回到时间x

思路:

涉及历史版本的询问,很容易想到主席树,然后尝试用线段树的思路用主席树写了下,疯狂WA,TLE,后面看了下其他人的博客。。。。发现不能加pushdown操作,因为一般来说pushdown更新完当前点后会向下更新子树,这样会新增很多点,其实我们可以将向下更新子树的操作省略,每次从根节点向下到需要的区间的过程中加上经过的点的lazy值就好了这样就实现了向下更新,且不会建过多的点。

还有因为计算从根到所求区间过程经过的标记数组对所求区间值的影响我们写法是:lazy*(R-L+1)所以查询操作没有用完全版线段树那种写法,换了一种,之前的写法,L,R,是不变的,但是我们是需要通过改变L,R,来表示当前标记数组作用的区间,需要改变L,R。

表达能力好弱啊。。。感觉讲不清楚想表达的思路。。。。难受

实现代码:、

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M = 1e5+;
ll a[M],sum[M*],lazy[M*];
int ls[M*],rs[M*],root[M],idx;
void pushup(int l,int r,int rt){
sum[rt] = sum[ls[rt]] + sum[rs[rt]] + 1LL*(r-l+)*lazy[rt];
} void build(int l,int r,int &rt){
rt = ++idx;lazy[rt] = ; sum[rt] = ;
if(l == r){
sum[rt] = a[l];
return ;
}
int m = (l + r) >> ;
build(l,m,ls[rt]);
build(m+,r,rs[rt]);
pushup(l,r,rt);
} void update(int old,int &rt,int L,int R,ll c,int l,int r){
rt = ++idx; ls[rt] = ls[old]; rs[rt] = rs[old];
sum[rt] = sum[old]; lazy[rt] = lazy[old];
if(L <= l&&R >= r){
sum[rt] += 1LL*(r-l+)*c;
lazy[rt] += c;
return ;
}
int m = (l + r) >> ;
if(L <= m) update(ls[old],ls[rt],L,R,c,l,m);
if(R > m) update(rs[old],rs[rt],L,R,c,m+,r);
pushup(l,r,rt);
} ll query(int L,int R,int l,int r,int rt){
if(L <= l&&R >= r) return sum[rt];
int m = (l + r) >> ;
ll ans = 1LL*(R-L+)*lazy[rt];
/* 这种写法是不对的
if(L <= m) ans += query(L,R,l,m,ls[rt]);
if(R > m) ans += query(L,R,m+1,r,rs[rt]);
*/
//正确写法
if(R <= m) ans += query(L,R,l,m,ls[rt]);
else if(L > m) ans += query(L,R,m+,r,rs[rt]);
else{
ans += query(L,m,l,m,ls[rt]);
ans += query(m+,R,m+,r,rs[rt]);
}
return ans;
} char op[];
int main()
{
int n,q,x,y;
ll z;
while(scanf("%d%d",&n,&q)!=EOF){
idx = ;memset(root,,sizeof(root));
for(int i = ;i <= n;i ++)
scanf("%lld",&a[i]);
build(,n,root[]);
int tim = ;
for(int i = ;i <= q;i ++){
scanf("%s",op);
if(op[] == 'C'){
scanf("%d%d%lld",&x,&y,&z);
update(root[tim],root[tim+],x,y,z,,n);
tim++;
}
else if(op[] == 'Q'){
scanf("%d%d",&x,&y);
printf("%lld\n",query(x,y,,n,root[tim]));
}
else if(op[] == 'H'){
int t;
scanf("%d%d%d",&x,&y,&t);
printf("%lld\n",query(x,y,,n,root[t]));
}
else if(op[] == 'B'){
scanf("%d",&x);
tim = x;
}
}
}
return ;
}

hdu 4348 To the moon (主席树 区间更新)的更多相关文章

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

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

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

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

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

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

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

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

  5. HDU 4348 To the moon 主席树

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

  6. HDU 4348 主席树区间更新

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

  7. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  8. HDU 4348 To the moon(主席树 区间更新)题解

    题意: 给一个数组A[1] ~ A[n],有4种操作: Q l r询问l r区间和 C l r v给l r区间每个数加v H l r t询问第t步操作的时候l r区间和 B t返回到第t步操作 思路: ...

  9. HDU 4348 To the moon (主席树区间更新)

    题意:首先给你n个数,开始时间为0,最后按照操作输出 给你四种操作: 1. C l r d :  在(l,r)区间都加上d,时间加一2. Q l r :  询问现在(l,r)的区间和3. H l r ...

  10. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

随机推荐

  1. 《MySQL必知必会》[06] 触发器

    1.触发器 MySQL中的触发器概念,和Java中的事件监听器有点相似.当你想要某条语句在某个事件发生时自动执行,就要用到触发器了. 触发器能响应如下三类语句: DELETE INSERT UPDAT ...

  2. Log4j使用笔记

            在工作过程中,常常需要查看后台日志,为了更好的记录日志,我们使用Log4j来记录日志. 一.maven依赖的配置         在maven中央库库里找到log4j的java包,添加 ...

  3. 一次永久解决cmd窗口汉字显示乱码

    对于编译出的程序,在 cmd 和 power shell 运行时都不能正确显示汉字. 网上查,可以再命令窗口修改: 1.打开CMD.exe命令行窗口 2.通过 chcp命令改变代码页,UTF-8的代码 ...

  4. 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)

    首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...

  5. [Oracle]发生 ora-06502 RMAN 在对 catalog DB 同期时出错的调查方法

    Catalog DB resync error: 1, setting on the server that starts the RMAN client $ Export EVENT_10928 = ...

  6. python语言程序设计5

    1, 评估函数eval() 去掉参数最外侧引号并执行余下语句的函数. 比如eval("1"),经过运行可以得到数字 1 去得是单双引号,不是括号哦.. 广泛来说,能将任何字符串的形 ...

  7. Hybrid小程序混合开发之路 - 数据交互

    HTML+CSS是历史悠久.超高自由度.控制精准.表现能力极强.编码简单.学习门槛超低.真跨平台的一种UI界面开发方式. 本文介绍的是微信小程序和H5混合开发的一种数据交互方式. 很多应用在原生界面中 ...

  8. 【亲测有效】Github无法访问或者访问速度的解决方案

    我相信,很多朋友都遇到了 Github 访问速度过慢的问题,我也是在此记下笔记,方便以后拿来使用. 第一步.修改Hosts 通过问题的搜索了解到 github 访问很慢一般通过修改 hosts 文件解 ...

  9. 使用阿里云cli管理安全组

    相比于python SDK方式,阿里云基于GO SDK开发了一整套CLI工具,可以通过调用RPC API来管理云资源,对编程能力不够的人来说是个福音. 而且,阿里云CLI的文档比SDK的文档更加全面, ...

  10. open-falcon ---客户机agent操作

    open-falcon的agent用于采集机器负载监控指标,比如cpu.idle.load.1min.disk.io.util等等,每隔60秒push给Transfer.agent与Transfer建 ...