链接:点击打开链接
题意:给N个数,有两种指令一种为询问区间内所有数的和,另一种为将区间内所有的数都加上一个指定值
代码:
#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int siz=100005;
long long tree[siz<<2],lazy[siz<<2];
void build(int l,int r,int rt){
lazy[rt]=0;
if(l==r){
scanf("%I64d",&tree[rt]);
return;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
void pushback(int rt,int p){
if(lazy[rt]){
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
tree[rt<<1]+=(lazy[rt]*(p-(p>>1)));
tree[rt<<1|1]+=(lazy[rt]*(p>>1));
lazy[rt]=0;
}
}
void Change(int L,int R,int p,int l,int r,int rt){
if(L<=l&&r<=R){
tree[rt]+=(p*(r-l+1));
lazy[rt]+=p;
return;
}
pushback(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m)
Change(L,R,p,l,m,rt<<1);
if(R>m)
Change(L,R,p,m+1,r,rt<<1|1);
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
long long query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R)
return tree[rt];
pushback(rt,r-l+1);
long long ans=0,m=(l+r)>>1;
if(L<=m)
ans+=query(L,R,l,m,rt<<1);
if(R>m)
ans+=query(L,R,m+1,r,rt<<1|1);
return ans;
} //线段树区间更新求和
int main(){
char c;
int n,m,u,v,w;
while(scanf("%d%d",&n,&m)!=EOF){
build(1,n,1);
while(m--){
cin>>c;
if(c=='Q'){
scanf("%d%d",&u,&v);
printf("%I64d\n",query(u,v,1,n,1));
}
else{
scanf("%d%d%d",&u,&v,&w);
Change(u,v,w,1,n,1);
}
}
}
return 0;
}