P3372 【模板】线段树 1
WA 10 pts
#include<iostream>
using namespace std;
const int N =100000;
struct node{
int l,r,sum,lazy;
};
int read(){
int a;scanf("%d",&a);
return a;
}
int a[N],n=read(),q=read();node tree[4*N+10];
int build(int num,int l,int r){
tree[num].l=l;tree[num].r=r;
if(l==r){
tree[num].sum=a[l];
return tree[num].sum;
}
int mid=(l+r)/2;
tree[num].sum=build(num*2,l,mid)+build(num*2+1,mid+1,r);
return tree[num].sum;
}
int ans_l,ans_r;
void add(int num,int k){
int l=tree[num].l,r=tree[num].r,mid=(l+r)/2;
if(ans_l<=l&&ans_r>=r){
tree[num].lazy+=k;
return;
}
if(ans_l<=mid)add(num*2,k);
if(ans_r>=mid+1)add(num*2+1,k);
if(l<=ans_l&&ans_r>=r)tree[num].sum+=k*(r-ans_l+1);
else if(ans_r>=l&&ans_l>=l)tree[num].sum+=k*(ans_r-l);
else if(l<=ans_l&&ans_r<=r)tree[num].sum+=k*(ans_r-ans_l);
//问题应该在这
}
int sum(int num){
int l=tree[num].l,r=tree[num].r,mid=(l+r)/2,ans=0;
if(ans_l<=l&&ans_r>=r){
// printf("+%d(l=%d,r=%d,sum=%d,lazy=%d)",tree[num].sum+(r-l+1)*(tree[num].lazy),l,r,tree[num].sum,tree[num].lazy);
return tree[num].sum+(r-l+1)*(tree[num].lazy);
}
if(tree[num].lazy!=0){
tree[num*2].lazy+=tree[num].lazy;
tree[num*2+1].lazy+=tree[num].lazy;
tree[num].sum+=(r-l+1)*(tree[num].lazy);
tree[num].lazy=0;
}
if(ans_l<=mid)ans+=sum(num*2);
if(ans_r>=mid+1)ans+=sum(num*2+1);
return ans;
}
int main(){
for(int i=1;i<=n;i++)a[i]=read();
build(1,1,n);
while(q--){
int moss=read();
ans_l=read(),ans_r=read();
if(moss==1){
int k=read();
add(1,k);
}else{
printf("%d\n",sum(1));
}
}
return 0;
}