Time Limit: 1000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
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.
Description
You‘ve been given N integers A[1], A[2],..., A[N]. On these integers, you need to implement the following operations:
- C l r d: Adding a constant d for every {Ai | l <= i <= r}, and increase the timestamp by 1, this is the only operation that will cause the timestamp increase.
- Q l r: Querying the current sum of {Ai | l <= i <= r}.
- H l r t: Querying a history sum of {Ai | l <= i <= r} in time t.
- 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 A1 A2 ... An ... (here following the m operations. )
Output
... (for each query, simply print the result. )
Example
Input 1: 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 Output 1: 4 55 9 15 Input 2: 2 4 0 0 C 1 1 1 C 2 2 -1 Q 1 2 H 1 2 1 Output 2: 0 1
可持久化线段树入门,区间更新pushdown的时候,需要新建俩个节点,不过内存消耗真大,我的调式过程都是根据oj返回的结果来加大数组或者减少数组,说多了都是泪....
/*
*=====================
*File Name:a.cpp
*Author: qqspeed
*Date: 2014年 07月 25日 星期五 20:08:21 CST
*=====================
*/
#pragma comment(linker,"/STACK:102400000,102400000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;
typedef long long ll;
#define rep(i,s,t) for(int i=s;i<t;i++)
#define red(i,s,t) for(int i=s-1;i>=t;i--)
#define ree(i,now) for(int i=head[now];i!=-1;i=edge[i].next)
#define clr(a,v) memset(a,v,sizeof a)
#define L t<<1
#define R t<<1|1
#define MID(l,r) int mid=(l+r)>>1
#define lowbit(x) (x&(-x))
#define SQR(a) ((a)*(a))
inline int input(){
int ret=0;bool isN=0;char c=getchar();
while(c<'0' || c>'9'){
if(c=='-') isN=1;
c=getchar();
}
while(c>='0' && c<='9'){
ret=ret*10+c-'0';
c=getchar();
}
return isN?-ret:ret;
}
inline void output(ll x){
if(x<0){
putchar('-');x=-x;
}
int len=0,data[20];
while(x){
data[len++]=x%10;x/=10;
}
if(!len) data[len++]=0;
while(len--)
putchar(data[len]+48);
putchar('\n');
}
const int N=100005;
const int MAXN=10000000;
int n,m,a[N],root[N],t;
ll sum[MAXN],lazy[MAXN];
int ls[MAXN],rs[MAXN],tot;
inline void copy(int k,int p){
sum[k]=sum[p];
lazy[k]=lazy[p];
ls[k]=ls[p];
rs[k]=rs[p];
}
inline void changeVal(int t,int l,int r,ll v){
sum[t]+=v*(r-l+1);
lazy[t]+=v;
}
inline void push_down(int t,int l,int r){
if(lazy[t] && l<r){
int a=(++tot),b=(++tot);
copy(a,ls[t]),copy(b,rs[t]);
MID(l,r);
changeVal(a,l,mid,lazy[t]);
changeVal(b,mid+1,r,lazy[t]);
ls[t]=a,rs[t]=b;
lazy[t]=0;
}
}
inline int build(int x,int y){
int k=(++tot);
lazy[k]=0;
if(x==y){
sum[k]=a[x];return k;
}
MID(x,y);
ls[k]=build(x,mid);
rs[k]=build(mid+1,y);
sum[k]=sum[ls[k]]+sum[rs[k]];
return k;
}
inline int add(int p,int l,int r,int x,int y,int v){
push_down(p,l,r);
int k=(++tot);copy(k,p);
if(l>=x && r<=y){
changeVal(k,l,r,v);return k;
}
MID(l,r);
if(y<=mid) ls[k]=add(ls[p],l,mid,x,y,v);
else if(x>mid) rs[k]=add(rs[p],mid+1,r,x,y,v);
else{
ls[k]=add(ls[p],l,mid,x,mid,v);
rs[k]=add(rs[p],mid+1,r,mid+1,y,v);
}
sum[k]=sum[ls[k]]+sum[rs[k]];
return k;
}
inline ll query(int p,int l,int r,int x,int y){
push_down(p,l,r);
if(l>=x && r<=y){
return sum[p];
}
MID(l,r);
if(y<=mid) return query(ls[p],l,mid,x,y);
else if(x>mid) return query(rs[p],mid+1,r,x,y);
return query(ls[p],l,mid,x,mid)+query(rs[p],mid+1,r,mid+1,y);
}
char op[2];
int x,y,z;
int main(){
while(~scanf("%d%d",&n,&m)){
t=tot=0;
rep(i,1,n+1) a[i]=input();
root[t]=build(1,n);
rep(i,0,m){
scanf("%s",op);
if(op[0]=='C'){
x=input(),y=input(),z=input();
t++;
root[t]=add(root[t-1],1,n,x,y,z);
}
else if(op[0]=='B'){
x=input();
t=x;
//tot=root[t];
}
else if(op[0]=='Q'){
x=input(),y=input();
output(query(root[t],1,n,x,y));
}
else if(op[0]=='H'){
x=input(),y=input(),z=input();
output(query(root[z],1,n,x,y));
}
}
puts("");
}
return 0;
}