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

n m 


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;
}

 

    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/4746060.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞