码迷,mamicode.com
首页 > 其他好文 > 详细

线段树(区间加区间统计)

时间:2020-02-03 13:37:33      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:def   efi   its   upd   线段树   ons   print   lse   ret   

#include <bits/stdc++.h>    
#define ll long long
using namespace std;
const ll maxn=2e5*5+10;
struct re
{
    ll x,y,w,z;
};
re a[maxn];
ll b[maxn];
void up(ll k)
{
    a[k].z=a[k*2].z+a[k*2+1].z;
}
void down(ll k)
{
    a[k*2].w+=a[k].w;
    a[k*2].z+=(a[k*2].y-a[k*2].x+1)*a[k].w;
    a[k*2+1].w+=a[k].w;
    a[k*2+1].z+=(a[k*2+1].y-a[k*2+1].x+1)*a[k].w;   
    a[k].w=0;
}
void build(ll k,ll l,ll r)
{
    a[k].x=l,a[k].y=r,a[k].w=0;
    if (l==r)
    {       
        a[k].z=b[l];
        return;
    }
    ll mid=(l+r)/2;
    build(k*2,l,mid);
    build(k*2+1,mid+1,r);
    up(k);
}
void update(ll k,ll l,ll r,ll w)
{
    if (a[k].y<l||a[k].x>r) return;
    if (l<=a[k].x&&a[k].y<=r)
    {
        a[k].w+=w;
        a[k].z+=(a[k].y-a[k].x+1)*w;    
        return;
    }
    if (a[k].w) down(k);
    update(k*2,l,r,w);
    update(k*2+1,l,r,w);
    up(k);
}
ll query(ll k,ll l,ll r)
{
    if (a[k].y<l||a[k].x>r) return 0;
    if (l<=a[k].x&&a[k].y<=r) return a[k].z;
    if (a[k].w) down(k);
    return query(k*2,l,r)+query(k*2+1,l,r);
}
int main()
{
    ll n,m;
    cin>>n>>m;
    for (ll i=1;i<=n;i++) scanf("%lld",&b[i]);
    build(1,1,n);

    for (ll i=1;i<=m;i++)
    {
        ll x,y,z,w;
        scanf("%lld%lld%lld",&x,&y,&z);
        if (x==1)
        {
            scanf("%lld",&w);
            update(1,y,z,w);
        }
        else printf("%lld\n",query(1,y,z)); 
//      for (ll j=1;j<=10;j++) printf("%lld %lld %lld %lld\n",a[j].x,a[j].y,a[j].w,a[j].z);
    }
    
}

线段树(区间加区间统计)

标签:def   efi   its   upd   线段树   ons   print   lse   ret   

原文地址:https://www.cnblogs.com/reshuffle/p/12255187.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!