区间更新,区间查询(单点更新,区间查询懒得写了,修改一下insert参数吧)code:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct hp{
long long value;
}node[800001];
int n,m;
long long ans;
long long a[200001]={0},delta[2000001]={0};
void updata(int i)
{
node[i].value=node[i*2].value+node[i*2+1].value;
}
void paint(int i,long long a,int l,int r)
{
node[i].value+=a*(r-l+1);
delta[i]+=a;
}
void pushdown(int i,int l,int r)
{
int mid; mid=(l+r)/2;
paint(i*2,delta[i],l,mid);
paint(i*2+1,delta[i],mid+1,r);
delta[i]=0;
}
void build(int i,int l,int r)
{
if (l==r)
{
node[i].value=a[l];
return;
}
build(i*2,l,(l+r)/2);
build(i*2+1,(l+r)/2+1,r);
updata(i);
}
void query(int i,int l,int r,int x,int y)
{
int mid;
if ((x<=l)&&(y>=r))
{
ans+=node[i].value;
return;
}
if (delta[i]!=0)
pushdown(i,l,r);
mid=(l+r)/2;
if (x<=mid) query(i*2,l,mid,x,y);
if (y>mid) query(i*2+1,mid+1,r,x,y);
}
void insert(int i,int l,int r,int x,int y,int z)
{
int mid;
if ((x<=l)&&(y>=r))
{
paint(i,z,l,r);
return;
}
pushdown(i,l,r); mid=(l+r)/2;
if (x<=mid)
insert(i*2,l,mid,x,y,z);
if (y>mid)
insert(i*2+1,mid+1,r,x,y,z);
updata(i);
}
int main()
{
int i,kind,j,x,y;
long long z;
memset(delta,0,sizeof(delta));
scanf("%d",&n);
for (i=1;i<=n;++i)
scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
for (i=1;i<=m;++i)
{
scanf("%d",&kind);
if (kind==1)
{
scanf("%d%d%lld",&x,&y,&z);
insert(1,1,n,x,y,z);
}
if (kind==2)
{
scanf("%d",&x,&y);
ans=0;
query(1,1,n,x,y);
printf("%d\n",ans);
}
}
}