</pre>最原始的lazy思想,注意在update的时候lazy只会更新到所在区间,往下就不会更新了,所以在查询的时候要pushdown更新下端区间。<pre name="code" class="cpp">#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define lson l , m , rt<<1
#define rson m+1 , r , rt<<1|1
using namespace std;
#define maxn 900000
int n;
long long sum[maxn],lazy[maxn];
void pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(int rt,int num)
{
if(lazy[rt])
{
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
sum[rt<<1]+=(num-(num>>1))*lazy[rt];//左区间多一个
sum[rt<<1|1]+=(num>>1)*lazy[rt];
lazy[rt]=0;
}
}
void build(int l,int r,int rt)
{
lazy[rt]=0;
int m=(l+r)>>1;
if(l==r)
{
scanf("%lld",&sum[rt]);
return ;
}
build(lson);
build(rson);
pushup(rt);
return ;
}
void update(int l,int r,int rt,int x,int y,long long add)//更新函数
{
if(x<=l &&r<=y)
{
lazy[rt]+=add;
sum[rt]+=add*(r-l+1);
return;
}
int m=(l+r)>>1;
pushdown(rt,(r-l+1));
if(x<=m)
update(lson,x,y,add);
if(y>m)
update(rson,x,y,add);
pushup(rt);
return;
}
long long query(int l,int r,int rt,int x,int y)//查询函数
{
long long tmp=0;
int m=(l+r)>>1;
if(x<=l &&r<=y)
{
return sum[rt];
}
pushdown(rt,(r-l+1));
if(x<=m)
tmp+=query(lson,x,y);
if(y>m)
tmp+=query(rson,x,y);
return tmp;
}
int main()
{
char a;
int n,q;
int x,y;
long long z;
while(scanf("%d",&n)!=EOF)
{
int b,c;
long long d;
build(1,n,1);
scanf("%d",&q);
while(q--)
{
int flag;
scanf("%d",&flag);
if(flag==1)
{
scanf("%d%d%lld",&x,&y,&z);
update(1,n,1,x,y,z);
}
else
{
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,n,1,x,y));
}
}
}
return 0;
}