HDU 4348 To the moon(可持久化线段树)
To the moon
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 4287 Accepted Submission(s): 923
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可持久化线段树,这道题目会卡内存,所以在pushdown和pushup的时候,新建节点可能会超内存那么我就可以跳过pushup和pushdown#include <iostream> #include <string.h> #include <algorithm> #include <math.h> #include <stdlib.h> #include <stdio.h> using namespace std; typedef long long int LL; const int maxn=1e5; int rt[maxn*35+5]; int ls[maxn*35+5]; int rs[maxn*35+5]; int p; LL sum[maxn*35+5]; LL pos[maxn*35+5]; int n,m,t; int newnode() { ls[p]=rs[p]=sum[p]=pos[p]=0; return p++; } void build(int &node,int begin,int end) { if(!node) node=newnode(); if(begin==end) { scanf("%lld",&sum[node]); return; } int mid=(begin+end)>>1; build(ls[node],begin,mid); build(rs[node],mid+1,end); sum[node]=sum[ls[node]]+sum[rs[node]]; } void update(int &node,int begin,int end,int left,int right,int val) { sum[p]=sum[node];ls[p]=ls[node];rs[p]=rs[node]; pos[p]=pos[node]; node=p;p++; sum[node]+=1LL*val*(right-left+1); if(left==begin&&end==right) { pos[node]+=val; return; } int mid=(begin+end)>>1; if(right<=mid) update(ls[node],begin,mid,left,right,val); else if(left>mid) update(rs[node],mid+1,end,left,right,val); else { update(ls[node],begin,mid,left,mid,val); update(rs[node],mid+1,end,mid+1,right,val); } } LL query(int node,int begin,int end,int left,int right) { if(left<=begin&&end<=right) return sum[node]; LL ret=1LL*pos[node]*(right-left+1); int mid=(begin+end)>>1; if(right<=mid) ret+=query(ls[node],begin,mid,left,right); else if(left>mid) ret+=query(rs[node],mid+1,end,left,right); else { ret+=(query(ls[node],begin,mid,left,mid)+query(rs[node],mid+1,end,mid+1,right)); } return ret; } int main() { char x; while(scanf("%d%d",&n,&m)!=EOF) { t=0; p=0; build(rt[0],1,n); int l,r,d,time; LL ans; for(int i=1;i<=m;i++) { cin>>x; if(x=='C') { scanf("%d%d%d",&l,&r,&d); update(rt[++t]=rt[t-1],1,n,l,r,d); } else if(x=='Q') { scanf("%d%d",&l,&r); ans=query(rt[t],1,n,l,r); printf("%lld\n",ans); } else if(x=='H') { scanf("%d%d%d",&l,&r,&time); ans=query(rt[time],1,n,l,r); printf("%lld\n",ans); } else { scanf("%d",&time); t=time; } } } return 0; }