线段树1板子

咕咕咕

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
inline ll read()
{
    ll sum=0,p=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            p=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        (sum*=10)+=ch-'0';
        ch=getchar();
    }
    return sum*p;
}
const int N=100005;
int n,m;
ll lazy[N*4],sum[N*4];

ll don(ll x,ll l,ll r)
{
    if(lazy[x])
    {
        ll mid=(l+r)>>1;
        lazy[x*2]+=lazy[x];
        sum[x*2]+=(mid-l+1)*lazy[x];
        lazy[x*2+1]+=lazy[x];
        sum[x*2+1]+=(r-mid)*lazy[x];
        lazy[x]=0;
    }
}

void add(ll x,ll l,ll r,ll ql,ll qr,ll y)
{
    if(l==ql&&r==qr)
    {
        sum[x]+=(r-l+1)*y;
        lazy[x]+=y;
        return;
    }
    don(x,l,r);
    ll mid=(l+r)>>1;
    if(qr<=mid)
        add(x*2,l,mid,ql,qr,y);
    else if(ql>mid)
        add(x*2+1,mid+1,r,ql,qr,y);
    else
    {
        add(x*2,l,mid,ql,mid,y);
        add(x*2+1,mid+1,r,mid+1,qr,y);
    }
    sum[x]=sum[x*2]+sum[x*2+1];
}

ll query(ll x,ll l,ll r,ll ql,ll qr)
{
    if(l==ql&&r==qr)
    {
        return sum[x];
    }
    don(x,l,r);
    ll mid=(l+r)>>1;
    if(qr<=mid)
        return query(x*2,l,mid,ql,qr);
    else if(ql>mid)
        return query(x*2+1,mid+1,r,ql,qr);
    else
        return query(x*2,l,mid,ql,mid)+query(x*2+1,mid+1,r,mid+1,qr);
}

int main()
{
    n=read(),m=read();
    for(int i=1; i<=n; i++)
    {
        ll a=read();
        add(1,1,n,i,i,a);
    }
    while(m--)
    {
        int opt=read();
        if(opt==1)
        {
            ll x=read(),y=read(),k=read();
            add(1,1,n,x,y,k);
        }
        else if(opt==2)
        {
            ll x=read(),y=read();
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}

 

posted @ 2019-10-25 19:32  darrrr  阅读(94)  评论(0编辑  收藏  举报