就是把文艺平衡树的反转变成加法标记?
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+5;
int val[maxn],sze[maxn],l[maxn],r[maxn],pri[maxn],cnt=0,rt=0;
bool tag[maxn];
int a[maxn];
int x,y,z;
void pushup(int k){
sze[k]=sze[l[k]]+sze[r[k]]+1;val[k]=val[l[k]]+val[r[k]]+a[k];
}
int newnode(int v){
val[++cnt]=v,sze[cnt]=1,l[cnt]=r[cnt]=0,pri[cnt]=rand();
return cnt;
}
void add(int k,int v){
tag[k]+=v;
val[k]+=sze[k]*v;
}
void pushdown(int k){
add(l[k],tag[k]);
add(r[k],tag[k]);
tag[k]=0;
}
void split(int now,int k,int &x,int &y){
if(!now){
x=y=0;return ;
}
pushdown(now);
if(sze[l[now]]+1<=k)x=now,split(r[now],k-(sze[l[now]]+1),r[now],y);
else y=now,split(l[now],k,x,l[now]);
pushup(now);
}
int merge(int x,int y){
if(!x||!y)return x+y;
if(pri[x]<pri[y]){
pushdown(x);
r[x]=merge(r[x],y);
pushup(x);
return x;
}else{
pushdown(y);
l[y]=merge(x,l[y]);pushup(y);
return y;
}
}
void print(int now){
if(!now)return ;
pushdown(now);
print(l[now]);cout<<val[now]<<" ";
print(r[now]);
}
int n,m;
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i],rt=merge(rt,newnode(a[i]));
for(int i=1;i<=m;i++){
int l,r,k;
int ch;
cin>>ch>>l>>r;
split(rt,l-1,x,y);
split(y,r-l+1,y,z);
if(ch==2){
cout<<val[y]<<endl;
}
else{
cin>>k;
add(y,k);
}
rt=merge(merge(x,y),z);
}
return 0;
}