ForMyDream @ 2023-01-15 14:00:11
#include<iostream>
using namespace std;
#define lowbit(x) ((x)&-(x))
#define ll long long
#define maxn 100010
ll tree1[maxn],tree2[maxn],n,m;
// 在差分数组[x] 的位置增加 d
// 差分数组在这里没有表示出来,因为差分数组就是用 tree 来维护的,tree 就是差分数组+树状数组
void update1(ll x,ll d){
// 在差分数组[x] 的位置增加 d
// 差分数组在这里没有表示出来,因为差分数组就是用 tree 来维护的,tree 就是差分数组+树状数组
while (x<=maxn){
tree1[x]+=d; x+=lowbit(x);
}
}
void update2(ll x,ll d){
while (x<=maxn){
tree2[x]+=d; x+=lowbit(x);
}
}
ll sum1(ll x){
ll ans=0;
while (x>0){
ans+=tree1[x]; x-=lowbit(x);
}
return ans;
}
ll sum2(ll x){
ll ans=0;
while (x>0){
ans+=tree2[x]; x-=lowbit(x);
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
// 不用建立原数组了,可以直接将原数组的值代入 tree 中
cin>>n>>m;
ll a,old; // a 用于输入原数组的数据,old 存储原数组的上一个元素,用于构造差分
for (int i=1;i<=n;i++){
cin>>a;
update1(i,a-old); // 构造差分 差分[i]=原[i]-原[i-1]
update2(i,(i-1)*(a-old)); // 一开始就把 i-1 乘进去
old=a;
}
// cout<<sum1(3)<<endl;
while (m--){
ll q,l,r,d;
cin>>q;
if (q==1){
cin>>l>>r>>d;
update1(l,d);
update1(r+1,-d); // 差分数组常规操作
update2(l,d*(l-1)); // 这里的 i(要修改的地方) 就是 l ,乘上 i-1 也就是 l-1
update2(r+1,-d*r); // 同理,乘上 i-1 也就是乘上 r+1-1 -> r
}
else {
cin>>l>>r;
// cout<<r*sum1(r)<<' '<<sum2(r)<<' '<<(l-1)*sum1(l-1)<<" "<<sum2(l-1)<<endl;
cout<<r*sum1(r)-sum2(r)-(l-1)*sum1(l-1)+sum2(l-1)<<endl;
}
}
return 0;
}