rt,过不了样例/kk
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,u,x,y,z;
long long a[N],tree[4*N],lazy[4*N];
void push_up(int id)
{
tree[id]=tree[id*2]+tree[id*2+1];
} //从子节点更新父节点
void push_down(int id,int l,int r) //从父节点更新子节点
{
if(lazy[id]==0)return;
int mid=(l+r)/2;
lazy[id*2]+=lazy[id],lazy[id*2+1]+=lazy[id]; //更新两个子节点的懒标记
tree[id*2]+=lazy[id]*(mid-l+1),tree[id*2+1]+=lazy[id]*(r-mid); //更新两个字节点的总和
lazy[id]=0; //父节点的懒标记清零
}
void build(int id,int l,int r) //建线段树
{
if(l==r)tree[id]=a[l];
else
{
int mid=(l+r)/2;
build(id*2,l,mid),build(id*2+1,mid+1,r); //建左子树和右子树
push_up(id);
}
}
long long query(int id,int l,int r,int x,int y) //区间求和
{
if(l>=x&&r<=y)
{
if(lazy[id]!=0)tree[id]+=lazy[id],lazy[id]=0; //顺便更新懒标记
return tree[id];
}
push_down(id,l,r); //查询前顺便更新懒标记
int mid=(l+r)/2,res=0;
if(x<=mid)res+=query(id*2,l,mid,x,y);
if(y>mid)res+=query(id*2+1,mid+1,r,x,y);
return res;
}
void updata(int id,int l,int r,int x,int y,long long z) //区间更新
{
if(l>=x&&r<=y)tree[id]+=z*(r-l+1),lazy[id]+=z; //添加懒标记
else
{
push_down(id,l,r); //顺便更新懒标记
int mid=(l+r)/2;
if(x<=mid)updata(id*2,l,mid,x,y,z);
if(y>=mid)updata(id*2+1,mid+1,r,x,y,z);
push_up(id); //更新父节点
}
}
int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,1,n); //建线段树
for(int i=1;i<=m;i++)
{
cin>>u>>x>>y;
if(u==1)cin>>z,updata(1,1,n,x,y,z);
else cout<<query(1,1,n,x,y)<<'\n';
}
return 0;
}