const int N = 1e5 + 10;
int n, m;
int a[N];
struct Tree{
int l,r;
ll sum,add;
}tr[4*N];
void build(int u,int l,int r){
// l=tr[u].l;r=tr[u].r;
//注释掉的部分是典型的错误,对于build过程中我们是初始化编号对应区间节点,上面赋值逻辑反了
tr[u]={l,r};
if(l==r)tr[u].sum=a[l];
else{
int mid=l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
}
void pushdown(int u){
auto &root=tr[u],&b=tr[u<<1],&c=tr[u<<1|1];
if(root.add){
b.add+=root.add;b.sum+=(ll)(b.r-b.l+1)*root.add;
c.add+=root.add;c.sum+=(ll)(c.r-c.l+1)*root.add;
root.add=0;
}
}
void update(int u,int x,int y,ll d){
int l=tr[u].l, r=tr[u].r,mid=l+r>>1;
if(x<=l&&y>=r){
tr[u].sum+=(ll)(r-l+1)*d;
tr[u].add+=d;
}
else {
pushdown(u);
if(x<=mid)update(u<<1,x,y,d);
if(y>mid)update(u<<1|1,x,y,d);
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
}
ll query(int u,int x,int y){
int l=tr[u].l,r=tr[u].r,mid=l+r>>1;
if(x<=l&&y>=r)return tr[u].sum;
else {
pushdown(u);
ll ans=0;
if(x<=mid)ans+=query(u<<1,x,y);
if(y>mid)ans+=query(u<<1|1,x,y);
return ans;
}
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,1,n);
while(m--){
int op;cin>>op;
if(op==1){
int l,r,d;
cin>>l>>r>>d;
update(1,l,r,d);
}
else {
int l,r;
cin>>l>>r;
ll ans=query(1,l,r);
cout<<ans<<endl;
}
}
}
标签:ll,int,线段,tr,else,含懒,build,sum,模板
From: https://www.cnblogs.com/mathiter/p/17891869.html