POJ 3468 A Simple Problem with Integers

题目链接:POJ 3468 A Simple Problem with Integers

简单的线段树区间更新。

难点在于延迟更新的思想,简单说就是不要每次更新都更新到叶子节点,这样太消耗时间,所以每个节点都增加一个inc来记录增量的累加。当传参区间与当前节点区间相同时,改变该节点的inc,然后return,停止向下更新。

#include <iostream>
#include <stdio.h>

using namespace std;

const int MAX_N = 100000 + 1000;
const int MAX_M = MAX_N << 2;
struct Node
{
    int l,r;
    long long sum;
    long long inc;
};
int arr[MAX_N];
Node node[MAX_M];
int n,q;

void build(int l,int r,int i)
{
    node[i].l = l;
    node[i].r = r;
    node[i].sum = 0;
    node[i].inc = 0;
    if(l == r)
    {
        node[i].sum = arr[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(l,mid,i << 1);
    build(mid + 1,r,i << 1 | 1);
    node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum;
}
void add(int l,int r,int i,long long val)
{
    if(node[i].l == l && node[i].r == r)
    {
        node[i].inc += val;
        return;
    }
    node[i].sum += (r - l + 1) * val;
    int mid = (node[i].l + node[i].r) >> 1;
    if(mid < l)
        add(l,r,i << 1 | 1,val);
    else if(mid >= r)
        add(l,r,i << 1,val);
    else
    {
        add(l,mid,i << 1,val);
        add(mid + 1,r,i << 1 | 1,val);
    }
}
long long query(int l,int r,int i)
{
    if(node[i].l == l && node[i].r == r)
    {
        return node[i].sum + (node[i].r - node[i].l + 1) * node[i].inc;
    }
    node[i].sum += (node[i].r - node[i].l + 1) * node[i].inc;
    int mid = (node[i].l + node[i].r) >> 1;
    add(node[i].l,mid,i << 1,node[i].inc);
    add(mid + 1,node[i].r,i << 1 | 1,node[i].inc);
    node[i].inc = 0;
    if(mid < l)
        return query(l,r,i << 1 | 1);
    else if(mid >= r)
        return query(l,r,i << 1);
    else
        return query(l,mid,i << 1) + query(mid + 1,r,i << 1 | 1);
}
int main()
{
    while(scanf("%d %d",&n,&q) != EOF)
    {
        for(int i = 1;i <= n;i++)
            scanf("%d",&arr[i]);
        build(1,n,1);
        char c[3];
        int a,b;
        long long val;
        for(int i = 1;i <= q;i++)
        {
            scanf("%s",c);
            if(c[0] == 'Q')
            {
                scanf("%d %d",&a,&b);
                printf("%lld\n",query(a,b,1));
            }
            else if(c[0] == 'C')
            {
                scanf("%d %d %lld",&a,&b,&val);
                add(a,b,1,val);
            }
        }
    }
}


你可能感兴趣的:(POJ 3468 A Simple Problem with Integers)