区间更新,区间查询(单点更新,区间查询懒得写了,修改一下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); } } }