线段树的区间更新---A Simple Problem with Integers

POJ   3468

Description

给出了一个序列,你需要处理如下两种询问。

"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。

"Q a b" 询问[a, b]区间中所有值的和。

Input

第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.

第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。

接下来Q行询问,格式如题目描述。

Output

对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

思路:线段树区间更新。

本题代码是很好的线段树区间更新模板:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
const int maxn=100005;
struct Node
{
    LL sum,val;
} node[4*maxn];

void pushup(int i)
{
    node[i].sum=node[i<<1].sum+node[i<<1|1].sum;
}

void pushdown(int i,int m)
{
    if(node[i].val)
    {
        node[i<<1].val+=node[i].val;
        node[i<<1|1].val+=node[i].val;
        node[i<<1].sum+=(LL)node[i].val*(m-(m>>1));
        node[i<<1|1].sum+=(LL)node[i].val*(m>>1);
        node[i].val=0;
    }
}

void build(int l,int r,int i)
{
    node[i].val=0;
    if(l==r)
    {
        scanf("%I64d",&node[i].sum);
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,i<<1);
    build(mid+1,r,i<<1|1);
    pushup(i);
}

LL query(int L,int R,int l,int r,int i)
{
   if(L<=l&&r<=R)
    {
        return node[i].sum;
    }
    int mid=(l+r)>>1;
    pushdown(i,r-l+1);
    LL ans=0;
    if(L<=mid)ans+=query(L,R,l,mid,i<<1);
    if(mid<R)ans+=query(L,R,mid+1,r,i<<1|1);
    pushup(i);
    return ans;
}

void update(int L,int R,int add,int l,int r,int i)
{
     if(L<=l&&r<=R)
    {
        node[i].sum+=(LL)add*(r-l+1);
        node[i].val+=add;
        return ;
    }
    pushdown(i,r-l+1);
    int mid=(l+r)>>1;
    if(L<=mid)update(L,R,add,l,mid,i<<1);
    if(mid<R)update(L,R,add,mid+1,r,i<<1|1);
    pushup(i);
}

int main()
{
    int n,q,a,b;
    LL c;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        build(1,n,1);
        char s[3];
        while(q--)
        {
            scanf("%s",s);
            if(s[0]=='C')
            {
                scanf("%d%d%I64d",&a,&b,&c);
                update(a,b,c,1,n,1);
            }
            else if(s[0]=='Q')
            {
                scanf("%d%d",&a,&b);
                printf("%I64d\n",query(a,b,1,n,1));
            }
        }
    }
    return 0;
}

 

 

posted @ 2016-04-12 17:12  茶飘香~  阅读(167)  评论(0编辑  收藏  举报