首页 > 代码库 > POJ 3468 A Simple Problem with Integers(线段树区间更新)

POJ 3468 A Simple Problem with Integers(线段树区间更新)

题目地址:POJ 3468

打了个篮球回来果然神经有点冲动。。无脑的狂交了8次WA。。居然是更新的时候把r-l写成了l-r。。。

这题就是区间更新裸题。区间更新就是加一个lazy标记,延迟标记,只有向下查询的时候才将lazy标记向下更新。其他的均按线段树的来就行。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <stack>
using namespace std;
#define LL long long
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
const int MAXN=1e5+10;
LL sum[MAXN<<2];
LL lazy[MAXN<<2];
void PushUp(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int rt, int m)
{
    if(lazy[rt])
    {
        lazy[rt<<1]+=lazy[rt];
        lazy[rt<<1|1]+=lazy[rt];
        sum[rt<<1]+=lazy[rt]*(m-(m>>1));
        sum[rt<<1|1]+=lazy[rt]*(m>>1);
        lazy[rt]=0;
    }
}
void build(int l, int r, int rt)
{
    lazy[rt]=0;
    if(l==r)
    {
        scanf("%lld",&sum[rt]);
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int ll, int rr, int x, int l, int r, int rt)
{
    if(ll<=l&&rr>=r)
    {
        lazy[rt]+=x;
        sum[rt]+=(LL)x*(r-l+1);
        return ;
    }
    PushDown(rt, r-l+1);
    int mid=(l+r)>>1;
    if(ll<=mid) update(ll,rr,x,lson);
    if(rr>mid) update(ll,rr,x,rson);
    PushUp(rt);
}
LL query(int ll, int rr, int l, int r, int rt)
{
    if(ll<=l&&rr>=r)
    {
        return sum[rt];
    }
    PushDown(rt,r-l+1);
    LL ans=0;
    int mid=(l+r)>>1;
    if(ll<=mid) ans+=query(ll,rr,lson);
    if(rr>mid) ans+=query(ll,rr,rson);
    return ans;
}
int main()
{
    int n, q, i, a, b, c;
    char ch[3];
    scanf("%d%d",&n,&q);
    build(1,n,1);
    while(q--)
    {
        getchar();
        scanf("%s",&ch);
        if(ch[0]=='Q')
        {
            scanf("%d%d",&a,&b);
            LL ans=query(a,b,1,n,1);
            printf("%lld\n",ans);
        }
        else
        {
            scanf("%d%d%d",&a,&b,&c);
            update(a,b,c,1,n,1);
        }
    }
    return 0;
}