#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=200010*2;
long long n;
struct cc{
long long l,r,add,sum;
}tree[maxn*2];
long long yy[maxn];
void update(long long p)
{
tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;
return;
}
void spread(long long p)
{
if(!tree[p].add) return;
tree[p*2].add+=tree[p].add;
tree[p*2+1].add+=tree[p].add;
tree[p*2].sum+=tree[p].add*(tree[p*2].r-tree[p*2].l+1);
tree[p*2+1].sum+=tree[p].add*(tree[p*2+1].r-tree[p*2+1].l+1);
tree[p].add=0;
update(p);
return;
}
void build(long long l,long long r,long long p)
{
tree[p].l=l,tree[p].r=r;
if(l==r)
{
tree[p].sum=yy[l];
return;
}
long long mid=(tree[p].l+tree[p].r)/2;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
update(p);
return;
}
void change(long long l,long long r,long long p,long long v)
{
if(l<=tree[p].l&&tree[p].r<=r)
{
tree[p].add+=v;
tree[p].sum+=v*(tree[p].r-tree[p].l+1);
return;
}
spread(p);
long long mid=(tree[p].l+tree[p].r)/2;
if(l<=mid) change(l,r,p*2,v);
if(mid+1<=r) change(l,r,p*2+1,v);
update(p);
return;
}
long long ask(long long l,long long r,long long p)
{
long long ans=0;
if(l<=tree[p].l&&tree[p].r<=r)
{
return tree[p].sum;
}
spread(p);
long long mid=(tree[p].l+tree[p].r)/2;
if(l<=mid) ans+=ask(l,r,p*2);
if(mid+1<=r) ans+=ask(l,r,p*2+1);
update(p);
return ans;
}
int main()
{
scanf("%lld",&n);
for(long long i=1;i<=n;i++)
{
scanf("%lld",&yy[i]);
}
build(1,n,1);
long long q;
scanf("%lld",&q);
for(long long i=1;i<=q;i++)
{
long long x;
scanf("%lld",&x);
if(x==1)
{
long long y,z,v;
scanf("%lld%lld%lld",&y,&z,&v);
change(y,z,1,v);
}
if(x==2)
{
long long y,z;
scanf("%lld%lld",&y,&z);
printf("%lld\n",ask(y,z,1));
}
}
return 0;
}
线段树模板
最新推荐文章于 2024-10-11 21:43:15 发布