HDU 4348 To the moon(可持久化线段树)

来源:互联网 发布:湖州公安网络报警网站 编辑:程序博客网 时间:2024/04/27 13:37

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.
 

Input
n m
A1 A2 ... An
... (here following the m operations. )
 

Output
... (for each query, simply print the result. )
 

Sample Input
10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 42 40 0C 1 1 1C 2 2 -1Q 1 2H 1 2 1
 

Sample Output
45591501
可持久化线段树,这道题目会卡内存,所以在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;}


 
0 0