http://poj.org/problem?id=3468
思路:lazy用法裸题。
呜呜呜,把r-l+1写反也是很尴尬
代码:
#include<bits/stdc++.h>
using namespace std;
#define lson l,mid,id*2
#define rson mid+1,r,id*2+1
#define LL long long
const int maxn=100100;
LL sum[maxn*4],lazy[maxn*4];
LL a[maxn];
void pushdown(LL id,LL m){
if(lazy[id]){
lazy[id*2]+=lazy[id];
lazy[id*2+1]+=lazy[id];
sum[id*2]+=(m-m/2)*lazy[id];
sum[id*2+1]+=(m/2)*lazy[id];
lazy[id]=0;///标记root状态已更新
}
}
void pushup(LL id){
sum[id]=sum[id*2]+sum[id*2+1];
lazy[id]=0;
}
void build(LL l,LL r,LL id){
if(l==r)
{
sum[id]=a[l];
lazy[id]=0;
return;
}
LL mid=(l+r)/2;
build(lson);
build(rson);
pushup(id);
}
void update(LL l,LL r,LL id,LL L,LL R,LL w){
if(l>=L && r<=R)
{
lazy[id]+=w;///标志当前这段区间更新了,但是这段区间下边的还没有更新
sum[id]=sum[id]+(r-l+1)*w;
return ;
}
pushdown(id,r-l+1);///如果这次更新过程中有靠下的,就会一直更新,下放
LL mid=(l+r)/2;
if(L<=mid){
update(lson,L,R,w);
}
if(R>mid){
update(rson,L,R,w);
}
pushup(id);
}
LL query(LL l,LL r,LL id,LL L,LL R){
/// cout<<"l:"<<l<<" r:"<<r<<endl;
/// cout<<"haoshen"<<endl;
LL ans=0;
if(l>=L &&r<=R){
return sum[id];
}
pushdown(id,r-l+1);///查的时候遇到靠下的也要一直下放
LL mid=(l+r)/2;
if(L<=mid){
ans+=query(lson,L,R);
}
if(R>mid){
ans+=query(rson,L,R);
}
pushup(id);
return ans;
}
int main()
{
LL n,m,x,y,z;
scanf("%lld%lld",&n,&m);
for(LL i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,n,1);
char ch;
for(int i=1;i<=m;i++){
cin>>ch;
if(ch=='Q'){
scanf("%lld%lld",&x,&y);
LL lala=query(1,n,1,x,y);
cout<<lala<<endl;
/// printf("%lld\n",query(1,n,1,x,y));
}
else
{
scanf("%lld%lld%lld",&x,&y,&z);
update(1,n,1,x,y,z);
}
}
return 0;
}