poj3468线段树区间更新

http://poj.org/problem?id=3468

裸的区间更新,lazy标记

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
const int maxn=100005;

struct Node
{
    LL sum,lazy;
}node[maxn<<2];

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

void pushdown(int rt,int len)
{
    if(node[rt].lazy)
    {
        node[rt<<1].lazy+=node[rt].lazy;
        node[rt<<1|1].lazy+=node[rt].lazy;
        node[rt<<1].sum+=(LL)node[rt].lazy*(len-(len>>1));
        node[rt<<1|1].sum+=(LL)node[rt].lazy*(len>>1);
        node[rt].lazy=0;//注意更新
    }
}

void build(int l,int r,int rt)
{
    node[rt].lazy=0;
    if(l==r)
    {
        scanf("%I64d",&node[rt].sum);
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    pushup(rt);
}

void update(int ll,int rr,int add,int l,int r,int rt)
{
    if(ll<=l&&rr>=r)
    {
        node[rt].sum+=(LL)add*(r-l+1);
        node[rt].lazy+=add;
        return ;
    }
    pushdown(rt,r-l+1);
    int m=(l+r)>>1;
    if(ll<=m)
    update(ll,rr,add,l,m,rt<<1);
    if(rr>m)
    update(ll,rr,add,m+1,r,rt<<1|1);
    pushup(rt);
}

LL query(int ll,int rr,int l,int r,int rt)
{
   if(ll<=l&&r<=rr)
    {
        return node[rt].sum;
    }
    int m=(l+r)>>1;
    pushdown(rt,r-l+1);
    LL ans=0;
    if(ll<=m) ans+=query(ll,rr,l,m,rt<<1);
    if(rr>m) ans+=query(ll,rr,m+1,r,rt<<1|1);
    pushup(rt);
    return ans;
}

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
            {
                scanf("%d%d",&a,&b);
                printf("%I64d\n",query(a,b,1,n,1));
            }
        }
    }
    return 0;
}

你可能感兴趣的:(poj3468线段树区间更新)