线段树(区间加区间统计)
Posted reshuffle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树(区间加区间统计)相关的知识,希望对你有一定的参考价值。
#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
",query(1,y,z));
// for (ll j=1;j<=10;j++) printf("%lld %lld %lld %lld
",a[j].x,a[j].y,a[j].w,a[j].z);
}
}
以上是关于线段树(区间加区间统计)的主要内容,如果未能解决你的问题,请参考以下文章