#include<iostream>
using namespace std;
long long m,n,ans;
struct node{
long long l,r,w,flag;
}a[100001<<2];
void build(int k,int l,int r){
a[k].l=l;a[k].r=r;
if(a[k].l==a[k].r){
cin>>a[k].w;
return;
}
build(k*2,l,(l+r)/2);
build(k*2+1,(l+r)/2+1,r);
a[k].w=a[k*2].w+a[k*2+1].w;
}
void down(int k){
a[k*2].flag+=a[k].flag;
a[k*2+1].flag+=a[k].flag;
a[k*2].w+=(a[k*2].r-a[k*2].l+1)*a[k].flag;
a[k*2+1].w+=(a[k*2+1].r-a[k*2+1].l+1)*a[k].flag;
a[k].flag=0;
}
void treechange(int k,int x,int y,int z){
if(a[k].l>=x&&a[k].r<=y){
a[k].w+=(a[k].r-a[k].l+1)*z;
a[k].flag+=z;
return;
}
if(a[k].flag)down(k);
int mid=(a[k].l+a[k].r)>>1;
if(x<=mid)treechange(k*2,x,y,z);
if(y>mid)treechange(k*2+1,x,y,z);
a[k].w=a[k*2].w+a[k*2+1].w;
}
void treefind(int k,int x,int y){
if(a[k].l>=x&&a[k].r<=y){
ans+=a[k].w;
return;
}
if(a[k].flag)down(k);
int mid=(a[k].l+a[k].r)>>1;
if(x<=mid)treefind(k*2,x,y);
if(y>mid)treefind(k*2+1,x,y);
a[k].w=a[k*2].w+a[k*2+1].w;
}
int main(){
cin>>n>>m;
build(1,1,n);
while(m--){
int g;
cin>>g;
if(g==1){
int x,y,z;
cin>>x>>y>>z;
treechange(1,x,y,z);
}
if(g==2){
int x,y;
cin>>x>>y;
treefind(1,x,y);
cout<<ans<<endl;
ans=0;
}
}
}
P3372 【模板】线段树
最新推荐文章于 2024-05-15 09:05:00 发布