zoukankan      html  css  js  c++  java
  • 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
    ",ans[i].x);
        }
        return 0;
    }
  • 相关阅读:
    每天一道Rust-LeetCode(2019-06-11)
    每天一道Rust-LeetCode(2019-06-10)
    每天一道Rust-LeetCode(2019-06-08)
    每天一道Rust-LeetCode(2019-06-07)
    每天一道Rust-LeetCode(2019-06-06)
    每天一道Rust-LeetCode(2019-06-05)
    每天一道Rust-LeetCode(2019-06-04)
    linux 基本命令
    使用 DrMemory 详细教程
    C++ 虚函数表解析
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4746060.html
Copyright © 2011-2022 走看看