敲一晚上但最后WA掉了。。。
TAT
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m,p=1;
ll tr[N*3],mark[N*3];
inline void build(){
while(p<=n+1) p<<=1;
for(int i=1;i<=n;i++){
cin>>tr[p+i];
}
for(int i=p-1;i>0;i--){
tr[i]=tr[i<<1]+tr[i<<1|1];
}
}
inline void add(int l,int r,ll k){
int siz=1;
l=p+l-1,r=p+r+1;
while((l^r^1)!=0){
if(~l&1){
tr[l^1]+=siz*k;
mark[l^1]+=k;
}
if(r&1){
tr[l^1]+=siz*k;
mark[l^1]+=k;
}
l>>=1,r>>=1,siz<<=1;
tr[l]=tr[l<<1]+tr[l<<1|1]+mark[l]*siz;
tr[r]=tr[r<<1]+tr[r<<1|1]+mark[r]*siz;
}
while(l>0){
l>>=1,siz<<=1;
tr[l]=tr[l<<1]+tr[l<<1|1]+mark[l]*siz;
}
}
inline ll query(int l,int r){
ll ans=0;
int sizl=0,sizr=0,siz=1;
l=p+l-1,r=p+r+1;
while((l^r^1)!=0){
if(~l&1){
ans+=tr[l^1];
sizl+=siz;
}
if(r&1){
ans+=tr[l^1];
sizr+=siz;
}
l>>=1,r>>=1,siz<<=1;
ans+=mark[l]*sizl+mark[r]*sizr;
}
while(l>0){
l>>=1,r>>=1;
ans+=mark[l]*sizl;
}
return ans;
}
int main(){
cin>>n>>m;
build();
int opt,l,r;
ll k;
while(m--){
cin>>opt>>l>>r;
if(opt==1){
cin>>k;
add(l,r,k);
}
else{
cout<<query(l,r)<<'\n';
}
}
return 0;
}
zkw线段树做法