HDU4348 To the moon
| Time Limit: 2000MS | Memory Limit: 65536KB | 64bit IO Format: %I64d & %I64u |
Description
To The Moon is a independent game released in November 2011, it is a role-playing adventure game powered by RPG Maker.
The premise of To The Moon is based around a technology that allows us to permanently reconstruct the memory on dying man. In this problem, we'll give you a chance, to implement the logic behind the scene.
You‘ve been given N integers A [1], A [2],..., A [N]. On these integers, you need to implement the following operations:
1. C l r d: Adding a constant d for every {A i | l <= i <= r}, and increase the time stamp by 1, this is the only operation that will cause the time stamp increase.
2. Q l r: Querying the current sum of {A i | l <= i <= r}.
3. H l r t: Querying a history sum of {A i | l <= i <= r} in time t.
4. B t: Back to time t. And once you decide return to a past, you can never be access to a forward edition anymore.
.. N, M ≤ 10 5, |A [i]| ≤ 10 9, 1 ≤ l ≤ r ≤ N, |d| ≤ 10 4 .. the system start from time 0, and the first modification is in time 1, t ≥ 0, and won't introduce you to a future state.
Input
A 1 A 2 ... A n
... (here following the m operations. )
Output
Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4 2 4
0 0
C 1 1 1
C 2 2 -1
Q 1 2
H 1 2 1
Sample Output
4
55
9
15 0
1
Source
可持久化线段树模板题。
对于不同的时间建立不同的新结点,新结点按照线段树的规则连接各个被修改的结点的新址(修改时不在原结点修改,而是新建一个结点(类似于分层图什么的)),没有修改的区域就直接链接到旧树的结点(因此不能用root*2 root*2+1的方式算结点,而要用数组模拟指针记录子结点标号)。
由于新层和旧层修改的值不一样,所以lazy标记是不能持久化的,一层的lazy只能在一层用。具体的解决方法见代码。
↑看到有大神说lazy标记持久化的方法是,对每个lazy记录时间戳,只有其标记时间与当前所要求的状态的时间相同时,才计算。然而看上去好麻烦。
代码基本靠抄。
看到有人说这题卡内存,就特意把数组开小了,结果依旧MLE。折腾一个多小时无果,怒把数组开到300w,居然A了。
↑想了想,大概MLE是因为动态申请新节点时,因为t数组越界,申请到了超大的节点值,直接炸掉内存,所以MLE而不是RE。
感到内存学问博大精深。
/*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#define LL long long
#define mid (l+r)/2
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m;
int data[mxn];
struct node{
int lc,rc;
LL sum,mk;
}t[];
int root[mxn];
int nct=;
int ntime=;
void Build(int l,int r,int &rt){
t[++nct]=t[rt];
rt=nct;
if(l==r){
t[rt].sum=data[l];
return;
}
Build(l,mid,t[rt].lc);
Build(mid+,r,t[rt].rc);
t[rt].sum=t[t[rt].lc].sum+t[t[rt].rc].sum;
return;
}
void add(int L,int R,int v,int l,int r,int &rt){
t[++nct]=t[rt];
rt=nct;
t[rt].sum+=(LL)v*(min(R,r)-max(l,L)+);
if(L<=l && r<=R){
t[rt].mk+=v;
return;
}
if(L<=mid)add(L,R,v,l,mid,t[rt].lc);
if(R>mid)add(L,R,v,mid+,r,t[rt].rc);
return;
}
LL query(int L,int R,int l,int r,int rt){
if(L<=l && r<=R)return t[rt].sum;
LL res=t[rt].mk*1LL*(min(R,r)-(max(L,l))+);
if(L<=mid)res+=query(L,R,l,mid,t[rt].lc);
if(R>mid)res+=query(L,R,mid+,r,t[rt].rc);
return res;
}
int main(){
char op[];
int i,j,x,y,a;
while(~scanf("%d%d",&n,&m)){
ntime=;nct=;
for(i=;i<=n;i++)
data[i]=read();
Build(,n,root[]);
for(i=;i<=m;i++){
scanf("%s",op);
switch(op[]){
case 'Q':{
x=read();y=read();
printf("%lld\n",query(x,y,,n,root[ntime]));
break;
}
case 'C':{
x=read();y=read();a=read();
++ntime;
root[ntime]=root[ntime-];
add(x,y,a,,n,root[ntime]);
break;
}
case 'H':{
x=read();y=read();a=read();
printf("%lld\n",query(x,y,,n,root[a]));
break;
}
case 'B':{
ntime=read();
break;
}
}
}
}
return ;
}
HDU4348 To the moon的更多相关文章
- [HDU4348]To the moon(主席树+标记永久化)
学可持久化treap的时候才发现自己竟然没写过需要标记下传的主席树,然而现在发现大部分操作都可以标记永久化,下传会增大占用空间. 这题一种写法是和普通的线段树一样标记下传,注意所有修改操作(包括put ...
- hdu4348 To the moon (主席树 || 离线线段树)
Problem Description Background To The Moon is a independent game released in November 2011, it is a ...
- hdu4348 - To the moon 可持久化线段树 区间修改 离线处理
法一:暴力! 让干什么就干什么,那么久需要可持久化线段树了. 但是空间好紧.怎么破? 不down标记好了! 每个点维护sum和add两个信息,sum是这段真实的和,add是这段整体加了多少,如果这段区 ...
- [HDU4348]To the moon(主席树)
传送门 对于这个题,显然要打lazy标记了,但是lazy标记pushdown的时候肯定会增加一大堆节点,然后就MLE了.(题解这么说的,我其实不会pushdown) 所以,就换另一种方式,把标记直接打 ...
- hdu4348 To the moon (可持久化线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4348 题目大意:给定含有n个数的序列,有以下四种操作 1.C l r d:表示对区间[l,r]中的数加 ...
- HDU4348 To the moon (主席树)
标记永久化,除非想\(MLE\) 忽然感到主席树不过是函数式的树套树 #include <iostream> #include <cstdio> #include <cs ...
- 【HDU4348】【主席树】To the moon
Problem Description BackgroundTo The Moon is a independent game released in November 2011, it is a r ...
- HDU4348:To the moon
浅谈主席树:https://www.cnblogs.com/AKMer/p/9956734.html 浅谈标记永久化:https://www.cnblogs.com/AKMer/p/10137227. ...
- Moon.Orm 入门总指南
注意:下面的pdf文件强烈建议下载或在线查看 1)旗舰版帮助文档点击查看或下载 2)http://pan.baidu.com/s/1hq7krFu(新手手册下载)(强烈推荐) 3)性能及规范下载,网友 ...
随机推荐
- codevs1842 递归第一次
难度等级:白银 1842 递归第一次 题目描述 Description 同学们在做题时常遇到这种函数 f(x)=5 (x>=0) f(x)=f(x+1)+f(x+2)+1 (x<0) 下面 ...
- C#加密解密大全
1.方法一 (不可逆加密) public string EncryptPassword(string PasswordString,string PasswordFormat ) { ...
- linux:nohup 不生成 nohup.out的方法
nohup java -jar /xxx/xxx/xxx.jar >/dev/null 2>&1 & 关键在于最后的 >/dev/null 2>&1 部 ...
- java 利用JAX-RS快速开发RESTful 服务
JAX-RS(Java API for RESTful Web Services)同样也是JSR的一部分,详细规范定义见 https://jcp.org/en/jsr/detail?id=311 .从 ...
- bash中变量+=,if大小判断,随机休眠
#!/bin/bash index= while true;do echo "hello" (( index+=)) echo `date "+%H:%M:%S" ...
- Loom工具类:Unity3D巧妙处理多线程
Loom代码不多,只有168行, 然而却具备了子线程运行Action, 子线程与主线程交互的能力! public static Thread RunAsync(Action a) public sta ...
- matlab如何建立一个空矩阵,然后往里面赋值
x=:; y=[]; :length(x) % y=[y;x(i)];%把每一个x都放到Y里,成为一列 y=[y,x(i)];%把每一个x都放到Y里,成为一行 end
- Ubuntu安装出现左上角光标一直闪解决方式
Ubuntu安装出现左上角光标一直闪解决方式: 01下载ubunu http://cn.ubuntu.com/download/ 02.软碟通 http://pan.baidu.com/s/1qY8O ...
- 【JavaEE企业应用实战学习记录】getConnListener
Listener:当Web应用在Web容器中运行时,Web应用内部会不断地发生各种事件,如Web应用被启动.Web应用被停止,用户Session开始,用户session结束.用户请求到达等,这些对We ...
- Spring + SpringMVC + MyBatis
1.需求说明实现用户通过数据库验证登录需求,采用Myeclipse+Tomcat 6.0+Mysql 5.0+JDK 1.6 2.数据库表开发所用是Mysql数据库,只建立单张用户表T_USER,表结 ...