POJ3468A Simple Problem with Integers(线段树区间更新)

https://vjudge.net/problem/POJ-3468

线段树区间更新,记录模板

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxa=100005;
ll c,s[maxa],lazy[maxa*4],sum[maxa*4];
int n,q,a,b;
char ch;

void build(int l,int r,int rt)
{
    int mid=(l+r)/2;
    if(l==r)
    {
        sum[rt]=s[mid];
        return ;
    }
    build(l,mid,rt*2);
    build(mid+1,r,rt*2+1);
    sum[rt]=sum[rt*2]+sum[rt*2+1];
}

void pushdown(int rt,int len)       ///rt为sum下标,后者是该区间的数组元素个数
{
    if(lazy[rt])
    {
        lazy[rt*2]  += lazy[rt];
        lazy[rt*2+1]+= lazy[rt];    ///父节点有标记,把标记给两个儿子
        sum[rt*2]   += (ll)(len-len/2)*lazy[rt];
        sum[rt*2+1] += (ll)(len/2)*lazy[rt];
        lazy[rt]=0;                 ///消除标记,底层的没有办法消除,
    }
}

void update(int l,int r,int rt,ll c)
{
    if(a<=l && r<=b)            ///如果区间在修改范围里,标记一下rt
    {
        lazy[rt]+=c;            ///如果没有消除,需要叠加,如果消除过,也是和0叠加
        sum[rt]+= (ll)c*(r-l+1);///直接加到大区间段,不要细分下去,节省时间
        return ;
    }
    pushdown(rt,r-l+1);///搞不好下面就需要用到标记区间的左右子树数据,所以都要先
    int mid = (l+r)/2;
    if(b<=mid)
        update(l,mid,rt*2,c);
    else if(a>mid)
        update(mid+1,r,rt*2+1,c);
    else
    {
        update(l,mid,rt*2,c);
        update(mid+1,r,rt*2+1,c);
    }
    sum[rt]=sum[rt*2]+sum[rt*2+1];
}
ll query(int l,int r,int rt)
{

    if( a<=l && r<=b )   return sum[rt];
    pushdown(rt,r-l+1);
    int mid = (l+r)/2;
    if(b<=mid)
        return query(l,mid,rt*2);
    else if(a>mid)
        return query(mid+1,r,rt*2+1);
    else
    return query(l,mid,rt*2)+query(mid+1,r,rt*2+1);
}

int main()
{
    memset(lazy,0,sizeof(lazy));
    memset(sum,0,sizeof(sum));
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
        scanf("%lld",&s[i]);
    build(1,n,1);

    while(q--)
    {
        getchar();///吸收回车键
        scanf("%c",&ch);
        if(ch=='Q')
        {
            scanf("%d%d",&a,&b);

            printf("%lld\n",query(1,n,1));
        }
        else
        {
            scanf("%d%d%lld",&a,&b,&c);
            update(1,n,1,c);
        }
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/shoulinniao/p/9441584.html