zoukankan      html  css  js  c++  java
  • POJ-3468-A Simple Problem with integers

    链接:https://vjudge.net/problem/POJ-3468

    题意:

    给定n个树,存在区间更新和区间查找。

    思路:

    区间更新,延迟标记。

    延迟标价某个节点表示,下面的节点存在延迟的值未更新,下一次查找到或使用时更新。

    减小时间消耗。

    代码:

    #include <iostream>
    #include <memory.h>
    #include <vector>
    #include <map>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    const int MAXN = 1e5 + 10;
    
    LL a[MAXN];
    LL segment[MAXN * 4];
    LL add[MAXN * 4];
    
    void Push_down(int root, int l, int r)
    {
        //线段树区间更新延迟更新操作
        if (add[root])//表示有延迟标记
        {
            //将上一层的标记移至下一层
            add[root << 1] += add[root];
            add[root << 1 | 1] += add[root];
            int mid = (l + r) >> 1;
            segment[root << 1] += add[root] * (mid - l + 1);//将下一层的线段树值更新
            segment[root << 1 | 1] += add[root] * (r - mid);
            add[root] = 0;//本曾延迟更新完毕,清楚本曾更新。
        }
    }
    
    void Build_tree(int root, int l, int r)
    {
        if (l == r)
        {
            segment[root] = a[l];
            return;
        }
        int next_node = root << 1;
        int mid = (l + r) / 2;
        Build_tree(next_node, l, mid);
        Build_tree(next_node + 1, mid + 1, r);
        segment[root] = segment[next_node] + segment[next_node + 1];
    }
    
    void Update(int root, int l, int r, int ql, int qr, int c)
    {
        if (ql > r || qr < l)
            return;
        if (ql <= l && r <= qr)
        {
            segment[root] += c * (r - l + 1);
            //更新查找区间
            add[root] += c;
            //延迟更新标记
        }
        else
        {
            Push_down(root, l, r);//更新此点的延迟标记
            int mid = (l + r) / 2;
            Update(root << 1, l, mid, ql, qr, c);
            Update(root << 1 | 1, mid + 1, r, ql, qr, c);
            segment[root] = segment[root << 1] + segment[root << 1 | 1];
        }
    }
    
    LL Query(int root, int l, int r, int ql, int qr)
    {
        if (ql > r || qr < l)
            return 0LL;
        if (ql <= l && r <= qr)
            return segment[root];
        Push_down(root, l, r);
        int mid = (l + r) / 2;
        LL res = 0;
        res += Query(root << 1, l, mid, ql, qr);
        res += Query(root << 1 | 1, mid + 1, r, ql, qr);
        return res;
    }
    
    int main()
    {
        int n, q;
        scanf("%d%d", &n, &q);
        for (int i = 1;i <= n;i++)
            cin >> a[i];
        Build_tree(1, 1, n);
        char op[10];
        int a, b, c;
        while (q--)
        {
            scanf("%s", op);
            if (op[0] == 'Q')
            {
                scanf("%d%d", &a, &b);
                printf("%lld
    ", Query(1, 1, n, a, b));
            }
            else
            {
                scanf("%d%d%d", &a, &b, &c);
                Update(1, 1, n, a, b, c);
            }
        }
    
    
        return 0;
    }
    

      

  • 相关阅读:
    python-多任务-进程
    注解_Annotation
    ZIP压缩输入/输出流
    什么是API,这篇文章让你豁然开朗
    异常处理(在控制台输入数据)
    控件监听与面板监听
    多态与继承
    Java——socketser与cli
    20170307
    20180305
  • 原文地址:https://www.cnblogs.com/YDDDD/p/10425755.html
Copyright © 2011-2022 走看看