Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u

Description

Background 
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

n m 
1 A 2 ... A n 
... (here following the m operations. )

Output

... (for each query, simply print the result. )

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的更多相关文章

  1. [HDU4348]To the moon(主席树+标记永久化)

    学可持久化treap的时候才发现自己竟然没写过需要标记下传的主席树,然而现在发现大部分操作都可以标记永久化,下传会增大占用空间. 这题一种写法是和普通的线段树一样标记下传,注意所有修改操作(包括put ...

  2. hdu4348 To the moon (主席树 || 离线线段树)

    Problem Description Background To The Moon is a independent game released in November 2011, it is a ...

  3. hdu4348 - To the moon 可持久化线段树 区间修改 离线处理

    法一:暴力! 让干什么就干什么,那么久需要可持久化线段树了. 但是空间好紧.怎么破? 不down标记好了! 每个点维护sum和add两个信息,sum是这段真实的和,add是这段整体加了多少,如果这段区 ...

  4. [HDU4348]To the moon(主席树)

    传送门 对于这个题,显然要打lazy标记了,但是lazy标记pushdown的时候肯定会增加一大堆节点,然后就MLE了.(题解这么说的,我其实不会pushdown) 所以,就换另一种方式,把标记直接打 ...

  5. hdu4348 To the moon (可持久化线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4348 题目大意:给定含有n个数的序列,有以下四种操作 1.C l r d:表示对区间[l,r]中的数加 ...

  6. HDU4348 To the moon (主席树)

    标记永久化,除非想\(MLE\) 忽然感到主席树不过是函数式的树套树 #include <iostream> #include <cstdio> #include <cs ...

  7. 【HDU4348】【主席树】To the moon

    Problem Description BackgroundTo The Moon is a independent game released in November 2011, it is a r ...

  8. HDU4348:To the moon

    浅谈主席树:https://www.cnblogs.com/AKMer/p/9956734.html 浅谈标记永久化:https://www.cnblogs.com/AKMer/p/10137227. ...

  9. Moon.Orm 入门总指南

    注意:下面的pdf文件强烈建议下载或在线查看 1)旗舰版帮助文档点击查看或下载 2)http://pan.baidu.com/s/1hq7krFu(新手手册下载)(强烈推荐) 3)性能及规范下载,网友 ...

随机推荐

  1. web一周

      学习web有一周了,老师进度有点小快,但是我还是感觉挺不错的.   对于一开始什么都不认识到能看懂是什么意思,并且可以写一些内容,我感觉还是比较欣慰,老师还是比较负责的,我每次都去找更远的代码学习 ...

  2. JAVA CDI 学习(3) - @Produces及@Disposes

    上一节学习了注入Bean的生命周期,今天再来看看另一个话题: Bean的生产(@Produces)及销毁(@Disposes),这有点象设计模式中的工厂模式.在正式学习这个之前,先来看一个场景: 基于 ...

  3. 高端大气上档次Ergotron Neo-Flex+MBP Retina的组合~

  4. MC700 安装双系统

    2011年买的MBP MC700给老婆用了一段时间后,老婆还不习惯不了Mac OS或是虚拟机,要求必须给安装windows,无奈时隔四年后,只能重新尝试在MC700上用bootcamp安装Window ...

  5. 学习Google Protocol buffer之语法

    上一篇结尾的时候问了几个问题,其实主要就是这个protoBuffer协议的语法,弄清楚语法后边才好开展工作嘛,不然大眼而对小眼儿,互相不认识,就没法玩耍了.其实就是学习怎么用google提供的这套 p ...

  6. [HDOJ5442]Favorite Donut(最大表示法)

    嗯……就是最小表示法改一下…… 这题就是把S串当作两个判断同构的串,然后就搞出最大的表示了 然后在反向再做一次 O(n)求最大表示,O(n)判断正反谁大

  7. JAVA多线程(二)

    Synchronized的使用: (一)synchronized:  Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当某个方法或者代 ...

  8. Windows10易升下载

    为了更好的帮助用户快速跨版本升级windows,退出Windows易升!在线下载,更新安装!网速快的话需要半个小时搞定! 升级完毕,如股票感觉OK.记得清理C盘Windows.old文件 01.磁盘- ...

  9. SharePoint 2013 安装图解

    转自: http://www.cnblogs.com/jianyus/archive/2013/02/01/2889653.html 介绍:文章就是SharePoint2013安装过程的图解,包括步骤 ...

  10. 1116Xlinux初学习之正则表达式和通配符

    一.正则表达式: 元字符是用来阐释字符表达式意义的字符,简言之,就是用来描述字符的字符. 正则表达式RE(Regular Expression)是由一串字符和元字符构成的字符串. 正则表达式的主要功能 ...