zoukankan      html  css  js  c++  java
  • POJ

    1、给出了一个序列,你需要处理如下两种询问。

    "C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。

    "Q a b" 询问[a, b]区间中所有值的和。

    2、线段树单点更新太费时,所以使用区间更新

    3、

    #include <cstdio>
    
    #define L(root) ((root) << 1)
    #define R(root) (((root) << 1) + 1)
    
    const int MAXN = 100001;
    int numbers[MAXN];
    
    struct st
    {
        // 区间范围
        int left, right;
        // 更新值、区间总和
        long long delta, sum;
    } st[MAXN * 4];
    
    // 建树代码基本不变
    void build(int root, int l, int r)
    {
        st[root].left = l, st[root].right = r, st[root].delta = 0;
        if (l == r)
        {
            st[root].sum = numbers[l];
            return;
        }
    
        int m = l + ((r - l) >> 1);
        build(L(root), l, m);
        build(R(root), m + 1, r);
        st[root].sum = st[L(root)].sum + st[R(root)].sum;
    }
    
    long long query(int root, int l, int r)
    {
        // 如查询区间恰等于节点区间,直接返回该区间总和即可
        if (st[root].left == l && st[root].right == r)
        {
            return st[root].sum;
        }
    
        // 否则需将当前区间的“缓冲”值更新下去并修正各节点区间的总和
        if (st[root].delta)
        {
            st[L(root)].delta += st[root].delta;
            st[R(root)].delta += st[root].delta;
            st[L(root)].sum += st[root].delta * (st[L(root)].right - st[L(root)].left + 1);
            st[R(root)].sum += st[root].delta * (st[R(root)].right - st[R(root)].left + 1);
            st[root].delta = 0;
        }
    
        int m = st[root].left + ((st[root].right - st[root].left) >> 1);
        if (r <= m)
        {
            return query(L(root), l, r);
        }
        else if (l > m)
        {
            return query(R(root), l, r);
        }
        else
        {
            return query(L(root), l, m) + query(R(root), m + 1, r);
        }
    }
    
    void update(int root, int l, int r, long long v)
    {
        // 如变更区间恰等于节点区间,只修正当前节点区间即可
        if (st[root].left == l && st[root].right == r)
        {
            st[root].delta += v;
            st[root].sum += v * (r - l + 1);
            return;
        }
    
        // 否则需向下修正相关节点区间
        if (st[root].delta)
        {
            st[L(root)].delta += st[root].delta;
            st[R(root)].delta += st[root].delta;
            st[L(root)].sum += st[root].delta * (st[L(root)].right - st[L(root)].left + 1);
            st[R(root)].sum += st[root].delta * (st[R(root)].right - st[R(root)].left + 1);
            st[root].delta = 0;
        }
    
        int m = st[root].left + ((st[root].right - st[root].left) >> 1);
        if (r <= m)
        {
            update(L(root), l, r, v);
        }
        else if (l > m)
        {
            update(R(root), l, r, v);
        }
        else
        {
            update(L(root), l, m, v);
            update(R(root), m + 1, r, v);
        }
        // 同时一定要记得修正当前节点区间的总和
        st[root].sum = st[L(root)].sum + st[R(root)].sum;
    }
    
    int main()
    {
        int N, Q;
        while (scanf("%d%d", &N, &Q) != EOF)
        {
            for (int i = 1; i <= N; ++i)
            {
                scanf("%d", &numbers[i]);
            }
    
            build(1, 1, N);
    
            char cmd;
            int l, r;
            long long v;
            while (Q--)
            {
                scanf(" %c", &cmd);
                scanf("%d%d", &l, &r);
                switch (cmd)
                {
                case 'Q':
                    printf("%lld
    ", query(1, l, r));
                    break;
    
                case 'C':
                    scanf("%lld", &v);
                    if (v)
                    {
                        update(1, l, r, v);
                    }
                    break;
                }
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    Oracle 推出 ODAC for Entity Framework 和 LINQ to Entities Beta版
    Entity Framework Feature CTP 5系列文章
    MonoDroid相关资源
    MSDN杂志上的Windows Phone相关文章
    微软学Android Market推出 Web Windows Phone Marketplace
    使用 Visual Studio Agent 2010 进行负载压力测试的安装指南
    MonoMac 1.0正式发布
    Shawn Wildermuth的《Architecting WP7 》系列文章
    使用.NET Mobile API即51Degrees.mobi检测UserAgent
    MongoDB 客户端 MongoVue
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4957239.html
Copyright © 2011-2022 走看看