省赛完了,回来补课
这线段树好像比我原先所想的要简单的多OTZ
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct SetmentTree{
/*
下标从1开始
MAXLEN=数组上限*4
*/
static const int MAXLEN=200000+10;
ll a[MAXLEN];
ll sum[MAXLEN*4];
ll lazy[MAXLEN*4];
int n;
void init(int an){
n=an;
memset(lazy,0,sizeof(lazy));
}
void down(int ln,int rn,int k){ //懒惰标记下推
lazy[k*2]+=lazy[k];
lazy[k*2+1]+=lazy[k];
sum[k*2]+=lazy[k]*ln;
sum[k*2+1]+=lazy[k]*rn;
lazy[k]=0;
}
void build(int l,int r,int k){ //构造线段树
if(l==r){
sum[k]=a[l];
return;
}
int m=(l+r)/2;
build(l,m,k*2);
build(m+1,r,k*2+1);
sum[k]=sum[k*2]+sum[k*2+1];
return;
}
void update(int l,int r,int k,int aiml,int aimr,int value){ //区间修改
if(aiml<=l&&aimr>=r){
sum[k]+=value*(r-l+1);
lazy[k]+=value;
return;
}
int m=(l+r)/2;
down(m-l+1,r-m,k);
if(aiml<=m) update(l,m,k*2,aiml,aimr,value);
if(aimr>m) update(m+1,r,k*2+1,aiml,aimr,value);
sum[k]=sum[k*2]+sum[k*2+1];
}
void query(int l,int r,int k,int aiml,int aimr,ll& ans){ //区间查询
if(l>=aiml&&r<=aimr){
ans+=sum[k];
return;
}
int m=(r+l)/2;
down(m-l+1,r-m,k);
if(aiml<=m) query(l,m,k*2,aiml,aimr,ans);
if(aimr>m) query(m+1,r,k*2+1,aiml,aimr,ans);
}
void reset(int l,int r,int k,int index,ll value){ //单点赋值
if(l==r){
sum[k]=value;
return;
}
int m=(l+r)/2;
down(m-l+1,r-m,k);
if(index<=m) reset(l,m,k*2,index,value);
else reset(m+1,r,k*2+1,index,value);
sum[k]=sum[k*2]+sum[k*2+1];
}
void add(int l,int r,int k,int index,ll value){ //单点修改
if(l==r){
sum[k]+=value;
return;
}
int m=(l+r)/2;
down(m-l+1,r-m,k);
if(index<=m) add(l,m,k*2,index,value);
else add(m+1,r,k*2+1,index,value);
sum[k]=sum[k*2]+sum[k*2+1];
}
ll ask(int l,int r,int k,int index){ //单点查询
if(l==r){
return sum[k];
}
int m=(l+r)/2;
down(m-l+1,r-m,k);
if(index<=m) return ask(l,m,k*2,index);
else return ask(m+1,r,k*2+1,index);
}
}st;
int main(){
ios::sync_with_stdio(0);
int n,m;
ll x,y,z;
cin>>n>>m;
st.init(n);
for(int i=1;i<=n;i++) cin>>st.a[i];
st.build(1,n,1);
while(m--){
cin>>x;
if(x==1){
cin>>x>>y>>z;
st.update(1,n,1,x,y,z);
}
else{
cin>>x>>y;
ll ans=0;
st.query(1,n,1,x,y,ans);
cout<<ans<<"\n";
}
}
return 0;
}