hdu 4348 To the moon (主席树 区间更新)
链接: 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 (主席树 区间更新)的更多相关文章
- hdu 4348 To the moon (主席树区间更新)
传送门 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q l r:查询当前时间戳区间[l,r]中所有数的和 . (3)H ...
- hdu 4348 To the moon 主席树区间更新
To the moon Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Prob ...
- HDU 4348 To the moon 主席树 在线更新
http://acm.hdu.edu.cn/showproblem.php?pid=4348 以前做的主席树没有做过在线修改的题做一下(主席树这种东西正经用法难道不是在线修改吗),标记永久化比较方便. ...
- hdu 4348 To the moon (主席树)
版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4348 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q ...
- HDU 4348 To the moon 主席树
题意: 给出一个长度为\(n(n \leq 10^5)\)的序列,最开始时间\(t=0\),支持下面几个操作: \(C \, l \, r \, d\):将区间\([l,r]\)每个数都加上\(d\) ...
- HDU 4348 主席树区间更新
To the moon Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
- 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步操作 思路: ...
- 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 ...
- HDU 1556 Color the ball(线段树区间更新)
Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...
随机推荐
- 什么是Mixin模式:带实现的协议
Mixin(织入)模式并不是GOF的<设计模式>归纳中的一种,但是在各种语言以及框架都会发现该模式(或者思想)的一些应用.简单来说,Mixin是带有全部实现或者部分实现的接口,其主要作用是 ...
- 交换左Ctrl键和Caps lock键
Windows 10 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control ...
- React-使用react-redux
react-redux可以方便在react中使用redux,我们就可以忘记subscribe,只需要记住reducer,action和dispatch就可以了.react-redux提供Provide ...
- ionic访问odoo 11接口
在架设完毕odoo 11的网站之后,第一次面临手机app该如何访问后台网站的问题,是不是模式类似asp.net mvc 那样的模式,或者还存在其他的访问方法,带着这个疑问与困惑,开始的我的研究学习之路 ...
- Flask系列学习
一.Flask系列学习(基础) Flask学习-前言 Flask学习-Flask基础之WSGI Flask学习-Flask app启动过程 Flask学习-Flask app接受第一个HTTP请求 F ...
- markdown操作手册
**1.标题** # h1 h1自带分割线 ## h2 ### h3 #### h4 ##### h5 ###### h6 **2.圆点** - 圆点 **3.分割线,-和*都可以** --- *** ...
- Unity 敌人波次设计
一.平均时间随机敌人 将所有种类敌人预制物体放在一个列表里面,每隔时间T从列表中随机选出一个生成在场景中. 二.时间加权紧迫度随机敌人 在随机情况下每种敌人出现的概率近似相等,当敌人种类较多时,有可能 ...
- Java Mongo 自定义序列化笔记
从insert方法入手 1. org.springframework.data.mongodb.repository.support.SimpleMongoRepository.java inse ...
- grep精确匹配搜索某个单词的用法 (附: grep高效用法小结))
grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正 ...
- M2阶段事后总结
设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述?我们的主要任务是将35w+个符合条件的网页,问答,文章放入数据库:爬取功能定义为以下几种:通用型爬取 ...