洛谷3372 线段树1(区间修改区间查询)

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define ls step<<1
#define rs step<<1|1
using namespace std;
const ll maxn=100020;
ll n,m,w[maxn<<2],tag[maxn<<2],a[maxn];

void Plus(ll step)
{
    w[step]=w[ls]+w[rs];
}

void build(ll step,ll l,ll r)
{
    tag[step]=0;
    if(l==r)
    {
        w[step]=a[l];
        return ;
    }
    ll mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    Plus(step);
}

void push_up(ll step,ll k,ll l,ll r)
{
    tag[step]+=k;
    w[step]+=(r-l+1)*k;
}

void push_down(ll step,ll l,ll r)
{
    ll mid=(l+r)>>1;
    push_up(ls,tag[step],l,mid);
    push_up(rs,tag[step],mid+1,r);
    tag[step]=0;
}

void update(ll step,ll k,ll l,ll r,ll nl,ll nr)
{
    if(nl<=l&&r<=nr)
    {
        tag[step]+=k;
        w[step]+=(r-l+1)*k;
        return ;
    }
    push_down(step,l,r);
    ll mid=(l+r)>>1;
    if(mid>=nl) update(ls,k,l,mid,nl,nr);
    if(mid<nr) update(rs,k,mid+1,r,nl,nr);
    Plus(step);
}

ll query(ll step,ll l,ll r,ll nl,ll nr)
{
    ll ans=0;
    if(nl<=l&&r<=nr) return w[step];
    push_down(step,l,r);
    ll mid=(l+r)>>1;
    if(mid>=nl) ans+=query(ls,l,mid,nl,nr);
    if(mid<nr) ans+=query(rs,mid+1,r,nl,nr);
    return ans;
}

int main()
{
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    build(1,1,n);
    for(ll i=1;i<=m;i++)
    {
        ll x,p,q,y;
        scanf("%lld%lld%lld",&x,&p,&q);
        if(x==1)
        {
            scanf("%lld",&y);
            update(1,y,1,n,p,q);
        }
        else printf("%lld\n",query(1,1,n,p,q));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Koiny/p/9883075.html