线段树模板区间加(含懒标记)

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; } } }

__EOF__

本文作者爱飞鱼
本文链接https://www.cnblogs.com/mathiter/p/17891869.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   potential-star  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示