深入理解lazytag
其实想了很久,我也不觉得是自己脑子反应慢,因为老会纠结一些奇怪的点..
也许,因此也对算法有了奇怪的理解吧。
#1,lazytag的作用是,在对同一区间进行多次操作再统一提问时,相当于先存操作数,提问时再一并处理。
lazytag下放的尽头是?放到树的某个节点管辖的区间可以被修改的区间完全包含时,就停止了。
#2.为什么update的时候要pushdown,为什么还要tree[i].sum=tree[i*2].sum+tree....
---
待填坑。。困了
---
很狗的我回来了,在发现阅读量居然不为0后,我决定填坑,不让看官失望地骂骂咧咧退出博客。
lazytag是用来偷懒的,但有两种情况不能偷懒。
首先,打了lazytag意味着该点管辖的所有区间都被执行过某种操作;
假设某次更新完,该点被优秀的coder你打上了lazytag,又来了一次更新,并且该次更新的区间和这个刚打上的区间有重合..
那么我们就要下放这个节点的lazytag,才能保证没有重叠的地方继续偷懒,有重叠的地方两次更新都考虑到了。
这就是在update前要放lazy的原因;
另外一个不能偷懒的事是query时
我就问一句都询问了你还不更新标记,你打算什么时候更新标记??再不更新就永远没有区间操作了!!
#include<bits/stdc++.h> using namespace std; typedef long long ll; struct node{ ll l,r,sum,lazy; }tree[1000000]; ll n,m,input[1000000]; void build(ll i,ll l,ll r) { if(l==r) { tree[i].l=l; tree[i].r=r; tree[i].sum=input[l]; return; } tree[i].lazy=0; tree[i].l=l; tree[i].r=r; ll mid=(l+r)>>1; build(i*2,l,mid); build(i*2+1,mid+1,r); tree[i].sum=tree[i*2].sum+tree[i*2+1].sum; } void pushdown(ll i) { if(tree[i].lazy!=0) { tree[i*2].lazy+=tree[i].lazy; tree[i*2+1].lazy+=tree[i].lazy; ll mid=(tree[i].l+tree[i].r)>>1; tree[i*2].sum+=tree[i].lazy*(mid-tree[i].l+1); tree[i*2+1].sum+=tree[i].lazy*(tree[i].r-mid); tree[i].lazy=0; } } void update(ll i,ll l,ll r,ll k) { if(tree[i].l>=l&&tree[i].r<=r) { tree[i].lazy+=k; tree[i].sum+=k*(tree[i].r-tree[i].l+1); return; } pushdown(i); ll mid=(tree[i].l+tree[i].r)>>1; if(tree[i*2].r>=l) { update(i*2,l,r,k); } if(tree[i*2+1].l<=r) { update(i*2+1,l,r,k); } tree[i].sum=tree[i*2].sum+tree[i*2+1].sum; return; } ll query(ll i,ll l,int r) { if(tree[i].l>=l&&tree[i].r<=r) { return tree[i].sum; } pushdown(i); ll ans=0; if(tree[i*2].r>=l) { ans+=query(i*2,l,r); } if(tree[i*2+1].l<=r) { ans+=query(i*2+1,l,r); } return ans; } int main() { /* 5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4 */ //freopen("9231.in","r",stdin); cin>>n>>m; for(ll i=1;i<=n;i++) { scanf("%lld",&input[i]); } build(1,1,n); for(ll i=1;i<=m;i++) { int a; cin>>a; if(a==2) { ll f,t; scanf("%lld%lld",&f,&t); cout<<query(1,f,t)<<endl; } else { ll from,to,k; scanf("%lld%lld%lld",&from,&to,&k); update(1,from,to,k); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了