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 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...
随机推荐
- VB6 加密解密字符串
Public Function EnCodeStr(ByVal password As String) As String Dim il_bit, il_x, il_y, il_z, il_len, ...
- 利用Costura.Fody制作绿色单文件程序(C#程序(含多个Dll)合并成一个Exe)
原文:利用Costura.Fody制作绿色单文件程序(C#程序(含多个Dll)合并成一个Exe) 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了.这 ...
- 在python中使用正则表达式(一)
在python中通过内置的re库来使用正则表达式,它提供了所有正则表达式的功能. 一.写在前面:关于转义的问题 正则表达式中用“\”表示转义,而python中也用“\”表示转义,当遇到特殊字符需要转义 ...
- 【教你玩转云计算】在阿里云一键安装快速部署Oracle11g
云计算时代提供了更方便可靠的IAAS,PAAS和SAAS平台.将已有或正在研发的项目迁移到云计算平台,和传统的服务器部署还是存在一些异同点. 本文手把手教你在阿里云平台快速的部署Oracle11g ...
- 线上mongodb 数据库用户到期时间修改的操作记录
登陆版权数据库,显示"此用户已到期",数据库使用的是mongodb,顾 需要将此用户的到期时间延长. 解决过程: 1)到网站对应tomcat配置里找出等里mongodb的信息(mo ...
- db2修改最大连接数
查看当前连接数,sample为数据库名db2 list applications for db sample db2 list applications for db sample show deta ...
- MariaDB第三章(select)
基本查询 --查询基本使用(条件,排序,聚合函数,分组,分页) --创建学生表 create table students ( id int unsigned not null auto_increm ...
- python-小知识点-14
''' python2 python3 ''' #python2 print() print 'abc' range() xrange() 生成器 raw_input() #python3 print ...
- C-代码笔记-输入输出
.ACSII 字符实质和整数存储方式相同 //2018年9月16日01:35:54 # include <stdio.h> int main(void) { '; // printf(&q ...
- Week 1 工程文档
计算器——工程文档 一.输入与格式 1.数据规模 本文档的输入基于如下的要求: (1)既然是小学生,我们假设他们不会计算超过10亿的数字. (2)既然是出考试题,那么也不会出超过10亿道题目. 也就是 ...