hdu 4348 可持久化线段树(区间和
来源:互联网 发布:js判断chrome浏览器 编辑:程序博客网 时间:2024/06/05 19:08
链接:戳这里
To the moon
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
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.
Input
n m
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
题意:
长度为n的整数序列,支持四个操作
1:Q l r 输出区间[l,r]的总和
2:C l r x 区间[l,r]的每个值都增加x,此时时间增加1
3:H l r t 询问在t时刻区间[l,r]的总和
4:B t 时间回到t
思路:
可持久化线段树区间询问的裸体
这题和这个是一样的,唯一的不同是内存限制变小了
今天学到了一种函数式线段树成段更新时节约内存的办法 。。。
先考虑朴素的仅支持成段加减的线段树,我们可以用方式解决:
1.正常的懒惰标记,当访问到带有懒惰标记节点的子区间时将标记下传;
2.不用下传的懒惰标记,我们用一个标记来记录当前节点的整段区间被累加了多少,当询问的时候我们在从根节点走到目标结点的过程中不断累加所经过节点上的标记值。。。
基于这两种思想,就有了函数式线段树的两种实现方式,第一种在pushdown的过程中会产生大量的结点,而第二种没有pushdown的过程,不会新建过多的节点
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<list>#include<stack>#include<iomanip>#include<cmath>#include<bitset>#define mst(ss,b) memset((ss),(b),sizeof(ss))///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;typedef long double ld;#define INF (1ll<<60)-1#define Max 30*100000using namespace std;int n,m;ll a[100100];struct node{ ll sum,lazy; int l,r;}tr[Max];int tot=0;void build(int &root,int l,int r){ root=++tot; tr[root].l=l; tr[root].r=r; tr[root].lazy=0; if(l==r) { tr[root].sum=a[l]; return ; } int mid=(l+r)/2; build(tr[root].l,l,mid); build(tr[root].r,mid+1,r); tr[root].sum=tr[tr[root].l].sum+tr[tr[root].r].sum;}void update(int &root,int l,int r,int last,int x,int y,ll v){ root=++tot; tr[root]=tr[last]; tr[root].sum+=1LL*(y-x+1)*v; //printf("root=%d l=%d r=%d sum=%I64d x=%d y=%d\n",root,tr[root].l,tr[root].r,tr[root].sum,x,y); if(x==l && y==r){ tr[root].lazy+=v; return ; } int mid=(l+r)/2; if(y<=mid) update(tr[root].l,l,mid,tr[last].l,x,y,v); else if(x>mid) update(tr[root].r,mid+1,r,tr[last].r,x,y,v); else { update(tr[root].l,l,mid,tr[last].l,x,mid,v); update(tr[root].r,mid+1,r,tr[last].r,mid+1,y,v); }}ll query(int root,int l,int r,int x,int y){ ll ans=tr[root].lazy*1LL*(y-x+1); //printf("root=%d l=%d r=%d sum=%I64d x=%d y=%d\n",root,tr[root].l,tr[root].r,tr[root].sum,x,y); if(x==l && y==r){ return tr[root].sum; } int mid=(l+r)/2; if(y<=mid) ans+=query(tr[root].l,l,mid,x,y); else if(x>mid) ans+=query(tr[root].r,mid+1,r,x,y); else { ans+=query(tr[root].l,l,mid,x,mid); ans+=query(tr[root].r,mid+1,r,mid+1,y); } return ans;}int root[Max];char s[110];int main(){ while(scanf("%d%d",&n,&m)!=EOF){ tot=0; for(int i=1;i<=n;i++) scanf("%I64d",&a[i]); build(root[0],1,n); int now=0; for(int i=1;i<=m;i++){ getchar(); int x,y,t; ll v; scanf("%s",s); if(s[0]=='Q') { scanf("%d%d",&x,&y); printf("%I64d\n",query(root[now],1,n,x,y)); } else if(s[0]=='C'){ scanf("%d%d%I64d",&x,&y,&v); now++; update(root[now],1,n,root[now-1],x,y,v); } else if(s[0]=='H'){ scanf("%d%d%d",&x,&y,&t); printf("%I64d\n",query(root[t],1,n,x,y)); } else { scanf("%d",&t); now=t; } } } return 0;}
0 0
- hdu 4348 可持久化线段树(区间和
- hdu 4348 可持久化线段树
- poj 2104 hdu 2665 区间第k大 可持久化线段树
- hdu 4417 可持久化线段树 (区间<=x的数的数量
- *hdu 2665 (可持久化线段树)
- hdu 5820 可持久化线段树
- 【HDU 4348】To the moon【可持久化线段树】
- 【可持久化线段树】【hdu 4348】To the moon
- 【HDU】4348 To the moon 【可持久化线段树】
- Hdu-4348 To the moon(可持久化线段树)
- 区间第K值(可持久化线段树)
- 区间第k小 poj2104 可持久化线段树
- hdu 2665 可持久化线段树求区间第K大值(函数式线段树||主席树)
- 【bzoj4571: [Scoi2016]美味】区间异或和最大 ,可持久化线段树(主席树)
- 【HDU4348】To The Moon-主席树(可持久化线段树)区间修改+区间询问
- hdu 2665 Kth number ( 可持久化线段树 )
- HDU 2665 Kth number 可持久化线段树
- HDU-2665 Kth number (可持久化线段树)
- Mahout算法集
- 基带通信相关概念
- linux静态库的生成与使用(转)
- 使用Java库中的类
- Linux的档案权限及目录配置(4)
- hdu 4348 可持久化线段树(区间和
- scala解析一段日志
- JAVA线程间通讯
- refresh的停车场
- Linux的档案权限及目录配置(一) (2)
- 高斯消元法 (模板)
- Android CoordinatorLayout
- SimpleCursorAdapter知识点关于一个: (IllegalArgumentException: column '_id' does not exist)_id字段的异常
- Linux系统调用与文件I/O(二)