zoukankan      html  css  js  c++  java
  • POJ 3468 A Simple Problem with Integers (线段树区间更新)

    题目链接:

    戳我

    题目大意:

    一组数,从 1 到 n,有两个操作,

    Q a b -->询问 a 到 b的这个区间的和

    C a b c  --->让a 到 b这个区间的每个数都加上 c

    样例解释:

    解题思路:

    自然线段树区间更新了。今天复习一下区间更新。。。

    //Author LJH
    //www.cnblogs.com/tenlee
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #define clc(a, b) memset(a, b, sizeof(a))
    #define LL long long
    using namespace std;
    
    const int inf = 0x3f;
    const int INF = 0x3f3f3f3f;
    const int maxn = 1e5+5;
    
    struct Node
    {
        int l, r;
        LL sum, add;
    }tree[maxn * 6];
    
    void Build(int i, int l, int r);
    void Update(int i, int l, int r, int val);
    void PushDown(int i);
    LL Query(int i, int l, int r);
    
    int main()
    {
        int n, q;
        int a, b, c;
        char op;
        while(~scanf("%d %d", &n, &q))
        {
            Build(1, 1, n);
            while(q--)
            {
                scanf(" %c", &op);
                if(op == 'Q')
                {
                    scanf("%d %d", &a, &b);
                    printf("%lld
    ", Query(1, a, b));
                }
                else 
                {
                    scanf("%d %d %d", &a, &b, &c);
                    Update(1, a, b, c);
                }
            }
        }
        return 0;
    }
    
    void Build(int i, int l, int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].add = 0;
        if(l == r)
        {
            scanf("%lld", &tree[i].sum);
            return;
        }
        int mid = (l + r) >> 1;
        Build(i << 1, l, mid);
        Build(i << 1 | 1, mid + 1, r);
        tree[i].sum = tree[i<<1].sum + tree[i<<1|1].sum;
    }
    
    void Update(int i, int l, int r, int val)
    {
        if(tree[i].l == l && tree[i].r == r) //刚好满足时,就标记了
        {
            tree[i].add += val;
            return;
        }
        tree[i].sum += (r - l + 1) * val; //注意此处是 r - l + 1, 而不是 tree[i].r - tree[i].l + 1
        int mid = (tree[i].l + tree[i].r) >> 1;
        if(r <= mid)
        {
            Update(i<<1, l, r, val);
        }
        else if(l > mid)
        {
            Update(i<<1|1, l, r, val);
        }
        else 
        {
            Update(i<<1, l, mid, val);
            Update(i<<1|1, mid+1, r, val);
        }
    }
    
    void PushDown(int i)
    {
        tree[i<<1|1].add += tree[i].add;
        tree[i<<1].add += tree[i].add;
        tree[i].sum += (tree[i].r  - tree[i].l + 1) * tree[i].add;
        tree[i].add = 0; //重置为0
     
    }
    
    LL Query(int i, int l, int r)
    {
        if(tree[i].add != 0)  // 向下更新
        {
            PushDown(i);
        }
        if(tree[i].l == l && tree[i].r == r)
        {
            return tree[i].sum;
        }
        int mid = (tree[i].l + tree[i].r) >> 1;
        if(r <= mid)
        {
            return Query(i<<1, l, r);
        }
        else if(l > mid)
        {
            return Query(i<<1|1, l, r);
        }
        else 
        {
            return (Query(i<<1, l, mid) + Query(i<<1|1, mid+1, r));
        }
    
    }
    

      

  • 相关阅读:
    代码对齐[UVA1593]
    数数字
    子序列
    细菌培养
    内联函数那些事情
    一个简单的问题
    头文件重复包含问题的一点笔记
    mapreduce 对文件分词读取
    hadoop hive-2.3.5安装
    hadoop sqoop 实例
  • 原文地址:https://www.cnblogs.com/tenlee/p/4892781.html
Copyright © 2011-2022 走看看