zoukankan      html  css  js  c++  java
  • HDU 4348 To the moon

    HDU_4348

        用可持久化线段树就可以实现O(1)的back操作,同时如果想效率比较高的话,推荐用单点修改+区间查询的模式替代下传标记的区间修改+区间查询的模式来完成对区间和的查询。

        至于如何不下传标记就能完成区间修改和区间求和可以参考ZKW的《统计的力量--线段树》的第59~60页。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 100010
    typedef long long LL;
    int N, M, node, T[MAXD], np[MAXD];
    LL A[MAXD];
    struct SegTree
    {
        int ls, rs;
        LL d, nd;
    }st[2560000];
    namespace ST
    {
        int build(int x = 1, int y = N)
        {
            int cur = ++ node, mid = x + y >> 1;
            st[cur].d = st[cur].nd = 0;
            if(x < y) st[cur].ls = build(x, mid), st[cur].rs = build(mid + 1, y);
            return cur;
        }
        int insert(int pre, int k, int d)
        {
            int t = ++ node, cur = t, x = 1, y = N;
            for(;;)
            {
                st[cur].d = st[pre].d + d, st[cur].nd = st[pre].nd + (LL)k * d;
                if(x == y) break;
                int mid = x + y >> 1;
                if(k <= mid)
                {
                    st[cur].ls = ++ node, st[cur].rs = st[pre].rs;
                    cur = node, pre = st[pre].ls, y = mid;
                }
                else
                {
                    st[cur].rs = ++ node, st[cur].ls = st[pre].ls;
                    cur = node, pre = st[pre].rs, x = mid + 1;
                }
            }
            return t;
        }
    }
    void init()
    {
        int i;
        A[0] = 0;
        for(i = 1; i <= N; i ++) scanf("%I64d", &A[i]), A[i] += A[i - 1];
        node = 0, T[0] = ST::build(), np[0] = node;
    }
    LL query(int k, int t)
    {
        int cur = T[t], x = 1, y = N;
        LL d = 0, nd = 0;
        if(k == 0) return 0;
        for(;;)
        {
            if(x == y)
            {
                d += st[cur].d, nd += st[cur].nd;
                break;
            }
            int mid = x + y >> 1;
            if(k <= mid) cur = st[cur].ls, y = mid;
            else
            {
                d += st[st[cur].ls].d, nd += st[st[cur].ls].nd;
                cur = st[cur].rs, x = mid + 1;
            }
        }
        return A[k] + k * d - nd + d;
    }
    void solve()
    {
        int i, x, y, t, d, cur = 0;
        char op[5];
        for(i = 0; i < M; i ++)
        {
            scanf("%s", op);
            if(op[0] == 'C')
            {
                scanf("%d%d%d", &x, &y, &d);
                ++ cur;
                T[cur] = ST::insert(T[cur - 1], x, d);
                if(y < N) T[cur] = ST::insert(T[cur], y + 1, -d);
                np[cur] = node;
            }
            else if(op[0] == 'Q')
            {
                scanf("%d%d", &x, &y);
                printf("%I64d\n", query(y, cur) - query(x - 1, cur));
            }
            else if(op[0] == 'H')
            {
                scanf("%d%d%d", &x, &y, &t);
                printf("%I64d\n", query(y, t) - query(x - 1, t));
            }
            else
                scanf("%d", &t), cur = t, node = np[t];    
        }
    }
    int main()
    {
        int t = 0;
        while(scanf("%d%d", &N, &M) == 2)
        {
            init();
            if(t ++) printf("\n");
            solve();    
        }
        return 0;    
    }
  • 相关阅读:
    LeetCode#34 Search for a Range
    Multiplication algorithm
    LeetCode#31 Next Permutation
    Spring boot之Hello World
    spring boot 简介
    分布式-网络通信-线程
    分布式-网络通信-协议
    分布式-架构图
    9.leetcode70-climbing stairs
    8.Leetcode69 Sqrt(x) 笔记
  • 原文地址:https://www.cnblogs.com/staginner/p/2676356.html
Copyright © 2011-2022 走看看