普通区间修改+区间查询
*lazy的使用
*建树
*区间add,区间query
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+500;
#define inf 0x3f3f3f3f3f
#define PII pair<int,int>
const int mod=998244353;
struct node
{
int l,r;//记录区间 such as : 1~n(father)
int val;
int lazy;//懒标记
}tree[N<<2];
//容量开4倍
int s[N];
int n,m;
void push_up(int now)
{
//向上更新
tree[now].val=tree[now<<1].val+tree[now<<1|1].val;
}
void push_down(int now)
{
if(tree[now].lazy)
{
//更新左右子树的lazy
tree[now<<1].lazy+=tree[now].lazy;
tree[now<<1|1].lazy+=tree[now].lazy;
//(lazy值*区间大小)
tree[now<<1].val+=tree[now].lazy*(tree[now<<1].r-tree[now].l+1);
tree[now<<1|1].val+=tree[now].lazy*(tree[now<<1|1].r-tree[now<<1|1].l+1);
//用过一次清空
tree[now].lazy=0;
}
}
void build(int now,int l,int r)
{
tree[now].l=l;
tree[now].r=r;
if(l==r)
{
tree[now].val=s[l];
return;
}
int mid=(l+r)/2;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
push_up(now);
}
void change(int now,int l,int r,int val)
{
if(l<=tree[now].l&&tree[now].r<=r)
{
tree[now].val+=(tree[now].r-tree[now].l+1)*val;
tree[now].lazy+=val;
return;
}
//向下更新
push_down(now);
int mid=(tree[now].l+tree[now].r)/2;
//找到合适的范围给add进去
if(l<=mid)
{
change(now<<1,l,r,val);
}
if(r>mid)
{
change(now<<1|1,l,r,val);
}
push_up(now);
}
int query(int now,int l,int r)
{
if(l<=tree[now].l&&tree[now].r<=r)
{
return tree[now].val;
}
push_down(now);
int res=0;
int mid=(tree[now].l+tree[now].r)/2;
if(l<=mid)
{
res+= query(now<<1,l,r);
}
if(r>mid)
{
res+= query(now<<1|1,l,r);
}
return res;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>s[i];
}
//建树
build(1,1,n);
while(m--)
{
int op;
cin>>op;
if(op==1)
{
int a,b,c;
cin>>a>>b>>c;
change(1,a,b,c);
}
else
{
int x,y;
cin>>x>>y;
cout<<query(1,x,y)<<endl;
}
}
}
signed main()
{
// int t;cin>>t;while(t--)
solve();
return 0;
}