poj 3468 A Simple Problem with Integers(线段树)

题目链接:http://poj.org/problem?id=3468

思路分析:使用sumv[i]记录一段线段区间的目前的sum,addv[i]记录在整个过程中对某一段线段区间上的所有增加值的和;

更新操作:将需要更新的区间分为多段不相交的区间,并在这些区间上更新该区间上增加的值,并修改这些区间的sum值以及其父节点的sum值;

查询操作:使用全局变量sum_ans,将查询的区间分为多段不相交的区间,并且进行增加的值的传递,将增加的值传给子节点,将这些区间的值

加上传递的增加的值即为所求;

 

代码如下:

#include <cstdio>
#include <iostream>
using namespace std;

const int MAX_N = 2 * 1000000 + 100;
long long sumv[MAX_N], addv[MAX_N];
long long sum_ans, arr[MAX_N];

void Build(int root, int l, int r, long long arr[])
{
    if (l == r)
    {
        addv[root] = arr[l];
        sumv[root] = arr[l];
    }
    else
    {
        int mid = (l + r) / 2;

        Build(2 * root, l, mid, arr);
        Build(2 * root + 1, mid + 1, r, arr);
        sumv[root] = sumv[2 * root] + sumv[2 * root + 1];
    }
}

void Updata(int o, int l, int r, long long add_value, int ql, int qr)
{
    if (l > qr || r < ql)
        return;
    if (ql <= l && r <= qr)
        addv[o] += add_value;
    else
    {
        int mid = (l + r) / 2;

        Updata(2 * o, l, mid, add_value, ql, qr);
        Updata(2 * o + 1, mid + 1, r, add_value, ql, qr);
    }

    sumv[o] = 0;
    if (l < r)
        sumv[o] = sumv[2 * o] + sumv[2 * o + 1];
    sumv[o] += addv[o] * (r - l + 1);
}

void Query(int o, int l, int r, int ql, int qr, long long add)
{
    if (l > qr || r < ql)
        return;
    if (ql <= l && r <= qr)
        sum_ans += sumv[o] + add * (r - l + 1);
    else
    {
        int mid = (l + r) / 2;

        Query(2 * o, l, mid, ql, qr, add + addv[o]);
        Query(2 * o + 1, mid + 1, r, ql, qr, add + addv[o]);
    }
}

int main()
{
    int num, query_times;

    scanf("%d %d", &num, &query_times);
    for (int i = 1; i <= num; ++i)
        scanf("%lld", &arr[i]);
    Build(1, 1, num, arr);

    for (int i = 0; i < query_times; ++i)
    {
        char str[2];
        int ql, qr, add_value;

        scanf("%s", str);
        if (str[0] == 'Q')
        {
            sum_ans = 0;
            scanf("%d %d", &ql, &qr);
            Query(1, 1, num, ql, qr, 0);
            printf("%lld\n", sum_ans);
        }
        else
        {
            scanf("%d %d %d", &ql, &qr, &add_value);
            Updata(1, 1, num, add_value, ql, qr);
        }
    }
    return 0;
}

你可能感兴趣的:(Integer)