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\n", Query(1, 1, n, a, b));
        }
        else
        {
            scanf("%d%d%d", &a, &b, &c);
            Update(1, 1, n, a, b, c);
        }
    }


    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/YDDDD/p/10425755.html