hdu 4348 主席树的区间更新
来源:互联网 发布:网络集成商 编辑:程序博客网 时间:2024/06/08 03:21
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 11, A 22,…, A NN. 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 ii| ≤ 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
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
题意:
一个长度为n的数组,4种操作 :
(1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 。
(2)Q l r:查询当前时间戳区间[l,r]中所有数的和 。
(3)H l r t:查询时间戳t区间[l,r]的和 。
(4)B t:将当前时间戳置为t 。
所有操作均合法 。
很明显可以想到每个时间点是一颗线段树,由于有时间上的限制,所以用主席树,对于每棵线段树进行一般的区间操作即可,但是这里不能使用pushdown 因为节点很多(因为你更新到下一棵树的时候复制是上一棵树的如果pushdown要对很多的树进行pushdown,(因为查询的时间不一定),会很麻烦),所以是人工的更新lazy标记统计和,让其的值确定下来,成为一个静态的,对后面的树不再有影响。所以区间更新和询问的时候不能像一般线段树一样,而是要指定特定的区间,而且都是更新在不同是时间点上 例如 laz[now] 和 ls[now],rs[now]。查询的时候人工求和的过程是 找到指定的区间 每一层累加上 要找的区间*laz[now],还有不同的地方就是在pushup的地方要把(r-l+1)*laz 也统计上去sum除,这样查询到的最后的sum才是对的
#include <bits/stdc++.h>using namespace std;const int N = 1e5+100;typedef long long ll;ll a[N];int ls[N*40],rs[N*40];typedef long long ll;ll sum[N*40],laz[N*40];int root[N*40];int tot;void pushup(int l,int r,int now){ sum[now]=sum[ls[now]]+sum[rs[now]]+1LL*(r-l+1)*laz[now];}int build(int l,int r){ int now=++tot; sum[now]=0; laz[now]=0; if(l==r) { sum[now]=a[l]; return now; } int mid=(l+r)>>1; ls[now]=build(l,mid); rs[now]=build(mid+1,r); pushup(l,r,now); return now;}void update(int pre,int &now,int L,int R,int l,int r,ll d){ now=++tot; ls[now]=ls[pre]; rs[now]=rs[pre]; sum[now]=sum[pre]; laz[now]=laz[pre]; if(l==L&&R==r) { sum[now]+=1LL*(R-L+1)*d; laz[now]+=d; return ; } int mid=(l+r)>>1; if(R<=mid) update(ls[pre],ls[now],L,R,l,mid,d); else if(L>mid) update(rs[pre],rs[now],L,R,mid+1,r,d); else{ update(ls[pre],ls[now],L,mid,l,mid,d); update(rs[pre],rs[now],mid+1,R,mid+1,r,d); } pushup(l,r,now);}ll query(int now,int L,int R,int l,int r){ if(L==l&&R==r) { return sum[now]; } ll res=1LL*(R-L+1)*laz[now]; int mid=(l+r)>>1; if(R<=mid) res+=query(ls[now],L,R,l,mid); else if(L>mid) res+=query(rs[now],L,R,mid+1,r); else { res+=query(ls[now],L,mid,l,mid); res+=query(rs[now],mid+1,R,mid+1,r); } return res;}int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { tot=0; int now=0; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); } root[0]=build(1,n); for(int i=1;i<=m;i++){ char ch; scanf(" %c",&ch); if(ch=='C') { int l,r; ll d; scanf("%d%d%lld",&l,&r,&d); update(root[now],root[now+1],l,r,1,n,d); now++; } else if(ch=='Q') { int l,r; scanf("%d%d",&l,&r); printf("%lld\n",query(root[now],l,r,1,n)); } else if(ch=='H') { int l,r,d; scanf("%d%d%d",&l,&r,&d); printf("%lld\n",query(root[d],l,r,1,n)); } else{ int d; scanf("%d",&d); now=d; } } }}
- hdu 4348 主席树的区间更新
- HDU 4348 To the moon(主席树区间更新)
- hdu-4348-To the moon-主席树在线区间更新
- HDU 4348To the moon 主席树 + 区间更新
- hdu-4348-To the moon(主席树更新,区间更新,区间和查询,保存历史版本返回)
- hdu-4348-To the moon-离线处理 or 主席树区间更新
- hdu 4348 To the moon(主席树,区间更新节省内存,经典)
- hdu 5919 主席树保留区间数的种类数目
- HDU 4348 To the moon 【主席树+区间修改】
- HDU 4348 To the moon [主席树 区间修改]
- HDU 4348 主席树(新的线段树区间查询方法)
- hdu 4348 主席树
- SPOJ TTM To The Moon 主席树的区间更新与查询
- 【主席树】 HDU 4417 Super Mario 区间内小于某值的个数
- HDU 2665 求静态区间的第k小值 主席树讲解。
- hdu 5919 Sequence II (主席树,求区间不同数的个数)
- hdu 5919 Sequence II(主席树,求区间不同数的个数)
- hdu 5790 prefix 主席树在线维护区间不同数的个数
- 步步紧逼!英特尔至强E7 v3对决IBM POWER8
- LeetCode#109. Convert Sorted List to Binary Search Tree
- Zookeeper集群搭建(涵盖命令详解)与Error contacting service. It is probably not running的问题解决
- Android匿名共享内存和MemoryFile
- C语言:列举system函数如何修改控制台背景及文字颜色
- hdu 4348 主席树的区间更新
- eclipse如何修改dynamic web module version
- iOS分享授权问题:-canOpenURL: failed ..."This app is not allowed to query for sscheme xx
- linux 下应用编程进程内存资源的限制
- Socket 编程
- angular2+ 利用FactoryProvider和APP_INITIALIZER初始化项目配置
- ansi与unicode字符串转换
- Android Design库控件使用
- cakephp(2.x)相关技巧[0]