SPOJ TTM - To the moon (主席树,区间更新,区间查询)
2017-07-14 11:22
567 查看
Background
To The Moon is a independent game released in November 2011, it is a role-playing adventure game powered by RPGMaker.
![](http://www.spoj.com/content/zukow:TTM.jpg)
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.
Description
You‘ve been given N integers A[1], A[2],..., A. On these integers, you need to implement the following operations:
C l r d: Adding a constant d for every {Ai | l <= i <= r}, and increase the timestamp by 1, this is the only operation that will cause the timestamp increase.
Q l r: Querying the current sum of {Ai | l <= i <= r}.
H l r t: Querying a history sum of {Ai | l <= i <= r} in time t.
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
n m A1 A2 ... An ... (here following the m operations. )
Output
... (for each query, simply print the result. )
Example
Input 1: 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 Output 1: 4 55 9 15 Input 2: 2 4 0 0 C 1 1 1 C 2 2 -1 Q 1 2 H 1 2 1 Output 2: 0 1
题意:N个数,M次操作,操作1,区间 l~r +d 时间+1 操作2,询问此时的区间和,操作3,询问t时的区间和,操作4,此时时间变成 t
主席树,对各个时间建线段树,用来查询区间和,需要注意的是延迟标记下沿时需要新建立2个节点,内存消耗过大,所以我们采用不下沿标记的方法,只需要在询问时将延迟标记和记录下来计算即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <queue>
#define mem(p,k) memset(p,k,sizeof(p));
#define rep(a,b,c) for(int a=b;a<c;a++)
#define pb push_back
//#define lson l,m,rt<<1
//#define rson m+1,r,rt<<1|1
#define inf 0x6fffffff
#define ll long long
using namespace std;
const int maxn=110005;
int n,m,tot,ti;
int h[maxn];
int lson[maxn*30],rson[maxn*30];
ll cur[maxn*30],sum[maxn*30];
void pushup(int now,int l,int r){
sum[now]=sum[lson[now]]+sum[rson[now]]+cur[now]*(r-l+1);//*******这里注意容易错
}
void build(int &now,int l,int r){
now=++tot;
cur[now]=0;
if(l==r){
scanf("%lld",sum+now);
return ;
}
int m=(l+r)>>1;
build(lson[now],l,m);
build(rson[now],m+1,r);
pushup(now,l,r);
}
void update(int &now,int pre,int L,int R,int val,int l,int r){
now=++tot;
lson[now]=lson[pre];
rson[now]=rson[pre];
cur[now]=cur[pre];
sum[now]=sum[pre];
if(L<=l && r<=R){
cur[now]+=val;
sum[now]+=(r-l+1)*val;//cout<<l<<r<<"=="<<sum[now]<<endl;
return;
}
int m=(l+r)>>1;
if(m>=L)update(lson[now],lson[pre],L,R,val,l,m);
if(m<R) update(rson[now],rson[pre],L,R,val,m+1,r);
pushup(now,l,r);
}
ll query(int rt,int L,int R,int l,int r,ll val){
if(L<=l && r<=R){
return val*(r-l+1)+sum[rt];
}
val+=cur[rt];
int m=(l+r)>>1;
ll ret=0;
if(m>=L)ret+=query(lson[rt],L,R,l,m,val);
if(m<R) ret+=query(rson[rt],L,R,m+1,r,val);
return ret;
}
int main(){
while(~scanf("%d%d",&n,&m)){
tot=0;
ti=0;
build(h[0],1,n);
while(m--){
int l,r,x;
char s[2];
scanf("%s",s);
if(s[0]=='C'){
scanf("%d%d%d",&l,&r,&x);
update(h[ti+1],h[ti],l,r,x,1,n);
ti++;
}
else if(s[0]=='Q'){
scanf("%d%d",&l,&r);
printf("%lld\n",query(h[ti],l,r,1,n,0));
}
else if(s[0]=='H'){
scanf("%d%d%d",&l,&r,&x);
printf("%lld\n",query(h[x],l,r,1,n,0));
}
else {
scanf("%d",&x);
ti=x;
}
}
}
return 0;
}
相关文章推荐
- hdu-4348-To the moon(主席树更新,区间更新,区间和查询,保存历史版本返回)
- SPOJ TTM To the moon(主席树+区间操作)
- vjudge: spoj--to the moon(主席树区间修改)
- hdu 4348 To the moon (主席树区间更新)
- HDU 4348 To the moon (主席树区间更新)
- hdu4348 To the moon(区间修改,区间查询的主席树)
- 【HDU - 4348】To the moon(主席树在线区间更新)
- SPOJ-TTM - To the moon(主席树,经典)
- hdu 4348 To the moon 主席树区间更新
- hdu 4348 To the moon(主席树,区间更新节省内存,经典)
- hdu-4348-To the moon-主席树在线区间更新
- hdu-4348-To the moon-离线处理 or 主席树区间更新
- HDU 4348 To the moon 主席树 + 区间更新
- HDU 4348 To the moon(主席树区间更新)
- SPOJ TTM To the moon(主席树)
- HDU 4348 To the moon 可持久化线段树,有时间戳的区间更新,区间求和
- HDU 4348 To the moon [主席树 区间修改]
- hdu4348 To the moon 区间更新
- hdu 4348 To the moon(主席树区间操作)
- HDU - 4348 To the moon (可持久化线段树,区间查询加累加)