hdu4348 To the moon
Problem 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 {Ai | 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 {Ai | l <= i <= r}.
3. H l r t: Querying a history sum of {Ai | 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 ≤ 105, |A[i]| ≤ 109, 1 ≤ l ≤ r ≤ N, |d| ≤ 104 .. 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.
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 {Ai | 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 {Ai | l <= i <= r}.
3. H l r t: Querying a history sum of {Ai | 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 ≤ 105, |A[i]| ≤ 109, 1 ≤ l ≤ r ≤ N, |d| ≤ 104 .. 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. )
A1 A2 ... An
... (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
正解:可持久化线段树
区间修改时新建一棵线段树,lazy数组不要下放,节省空间,回溯时上放就好。区间查询时查询root[i]就行,将查询答案加上经过的lazy。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 #define inf 1<<30 14 #define il inline 15 #define RG register 16 #define ll long long 17 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 18 19 using namespace std; 20 21 int ls[3000010],rs[3000010],lazy[3000010],root[100010],a[100010],n,m,sz,l,r,t,now; 22 ll sum[3000010]; 23 char ch[3]; 24 25 il int gi(){ 26 RG int x=0,q=0; RG char ch=getchar(); 27 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=1,ch=getchar(); 28 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q ? -x : x; 29 } 30 31 il void build(RG int &x,RG int l,RG int r){ 32 x=++sz; if (l==r){ sum[x]=a[l]; return; } RG int mid=(l+r)>>1; 33 build(ls[x],l,mid),build(rs[x],mid+1,r); sum[x]=sum[ls[x]]+sum[rs[x]]; return; 34 } 35 36 il void update(RG int last,RG int &now,RG int l,RG int r,RG int xl,RG int xr,RG int v){ 37 now=++sz,ls[now]=ls[last],rs[now]=rs[last],sum[now]=sum[last],lazy[now]=lazy[last]; 38 if (xl<=l && r<=xr){ sum[now]+=(r-l+1)*v,lazy[now]+=v; return; } RG int mid=(l+r)>>1; 39 if (xr<=mid) update(ls[last],ls[now],l,mid,xl,xr,v); 40 else if (xl>mid) update(rs[last],rs[now],mid+1,r,xl,xr,v); 41 else update(ls[last],ls[now],l,mid,xl,mid,v),update(rs[last],rs[now],mid+1,r,mid+1,xr,v); 42 sum[now]=sum[ls[now]]+sum[rs[now]]+lazy[now]*(r-l+1); return; 43 } 44 45 il ll query(RG int now,RG int l,RG int r,RG int xl,RG int xr,RG int la){ 46 if (xl<=l && r<=xr) return sum[now]+la*(r-l+1); RG int mid=(l+r)>>1; RG ll res=0; la+=lazy[now]; 47 if (xr<=mid) res=query(ls[now],l,mid,xl,xr,la); 48 else if (xl>mid) res=query(rs[now],mid+1,r,xl,xr,la); 49 else res=query(ls[now],l,mid,xl,mid,la)+query(rs[now],mid+1,r,mid+1,xr,la); 50 return res; 51 } 52 53 il void work(){ 54 for (RG int i=1;i<=n;++i) a[i]=gi(); build(root[0],1,n); 55 for (RG int i=1;i<=m;++i){ 56 scanf("%s",ch); 57 if (ch[0]=='C'){ l=gi(),r=gi(),t=gi(),now++; update(root[now-1],root[now],1,n,l,r,t); } 58 if (ch[0]=='Q'){ l=gi(),r=gi(); printf("%lld\n",query(root[now],1,n,l,r,0)); } 59 if (ch[0]=='H'){ l=gi(),r=gi(),t=gi(); printf("%lld\n",query(root[t],1,n,l,r,0)); } 60 if (ch[0]=='B') t=gi(),now=t; 61 } 62 return; 63 } 64 65 int main(){ 66 File("hdu4348"); 67 while (scanf("%d%d",&n,&m)==2) sz=now=0,work(); 68 return 0; 69 }