HDU 4348 To the moon 可持久化线段树,有时间戳的区间更新,区间求和
To the moon
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88748#problem/I
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
... (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
HINT
题意
可持久化线段树
查询第i个时间的区间和
查询现在的区间和
让时间增加一s,并区间修改
回到t秒
题解:
这种题,能离线就离线,在线做会MLE= =
按照时间建一棵树,然后直接暴力dfs,然后线段树修改,再不断回溯就好了
代码:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <stack> #include <map> #include <set> #include <queue> #include <iomanip> #include <string> #include <ctime> #include <list> #include <bitset> typedef unsigned char byte; #define maxn 110000 #define pb push_back #define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0) #define local freopen("in.txt","r",stdin) #define pi acos(-1) using namespace std; typedef long long SgTreeDataType; struct treenode { int L , R , mid ; SgTreeDataType sum , lazy; void updata(SgTreeDataType v) { sum += (R-L+1)*v; lazy += v; } }; treenode tree[maxn*4]; inline void push_down(int o) { SgTreeDataType lazyval = tree[o].lazy; tree[2*o].updata(lazyval) ; tree[2*o+1].updata(lazyval); tree[o].lazy = 0; } inline void push_up(int o) { tree[o].sum = tree[2*o].sum + tree[2*o+1].sum; } inline void build_tree(int L , int R , int o) { tree[o].L = L , tree[o].R = R,tree[o].sum = tree[o].lazy = 0; if (R > L) { int mid = (L+R) >> 1; build_tree(L,mid,o*2); build_tree(mid+1,R,o*2+1); } } inline void updata(int QL,int QR,long long v,int o) { int L = tree[o].L , R = tree[o].R; if (QL <= L && R <= QR) tree[o].updata(v); else { push_down(o); int mid = (L+R)>>1; if (QL <= mid) updata(QL,QR,v,o*2); if (QR > mid) updata(QL,QR,v,o*2+1); push_up(o); } } inline SgTreeDataType query(int QL,int QR,int o) { int L = tree[o].L , R = tree[o].R; if (QL <= L && R <= QR) return tree[o].sum; else { push_down(o); int mid = (L+R)>>1; SgTreeDataType res = 0; if (QL <= mid) res += query(QL,QR,2*o); if (QR > mid) res += query(QL,QR,2*o+1); push_up(o); return res; } } int n,m; struct Query { int type; long long x,y,z; }; Query P[maxn]; struct node { long long x; int y; }; bool cmp(node a,node b) { return a.y<b.y; } vector<node> ans; vector<int> E[maxn]; long long x; int Time[maxn]; char c[10]; void dfs(int x) { for(int i=0;i<E[x].size();i++) { int v = E[x][i]; if(P[v].type == 1) { updata(P[v].x,P[v].y,P[v].z,1); dfs(v); updata(P[v].x,P[v].y,-P[v].z,1); } else { ans.push_back((node){query(P[v].x,P[v].y,1),v}); } } } int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF) { ans.clear(); for(int i=0;i<maxn;i++) E[i].clear(); memset(Time,0,sizeof(Time)); memset(tree,0,sizeof(tree)); build_tree(1,n+100,1); for(int i=1;i<=n;i++) { scanf("%I64d",&x); updata(i,i,x,1); } int now = 0; for(int i=1;i<=m;i++) { scanf("%s",c); if(c[0]=='C') { P[i].type = 1; scanf("%I64d%I64d%I64d",&P[i].x,&P[i].y,&P[i].z); E[Time[now]].push_back(i); now++; Time[now]=i; } else if(c[0]=='Q') { P[i].type = 2; scanf("%I64d%I64d",&P[i].x,&P[i].y); E[Time[now]].push_back(i); } else if(c[0]=='H') { P[i].type = 2; scanf("%I64d%I64d%I64d",&P[i].x,&P[i].y,&P[i].z); E[Time[P[i].z]].push_back(i); } else { scanf("%I64d",&x); now = x; } } dfs(0); sort(ans.begin(),ans.end(),cmp); int len = ans.size(); for(int i=0;i<ans.size();i++) printf("%I64d\n",ans[i].x); } return 0; }