扫描线

之前写的搬一下


扫描线应该说是一种数据结构的维护思想,处理的问题经常是查询一段区间内子区间的信息,并且可以离线处理。

大致的流程是把询问离线下来,按某个东西排序,然后从 1n 遍历序列,不断加上维护的信息,在某些时刻(比如到达一个询问的端点时)把对应询问的答案给搞出来,放到数组里面,接下一个询问。

刚才有个大佬回复说:扫描线本质上就是把一个维度轴当做时间轴来看,然后拿点 DS 去维护这个“时间轴”前进过程中的变化。这就很形象地解释了修改和查询一起进行的过程。这样我们边修改边查询,修改 n 次查询 m 次,复杂度 O((n+m)logn)

大概的代码框架,很简单:

for(int i=1,j=1;i<=n;++i){
		update();
		while(j<=m&&q[j].r==i){
			ans[q[j].id]=query();
			++j;
		}
	}

P9991 Ynoi Easy Round 2023 TEST_107

我们考虑一个极长子区间可能是长啥样的,有三种可能:

1. [l,r]=[l,i],满足 ai+1=x,j[l,i],ajx

2. [l,r]=[i,r],满足 ai1=x,j[i,r],ajx

3. l>l,r<r,满足 al1=ar+1=x,j[l,r],ajx

先考虑 1,我们记录 lasi 表示上一个 ai 所在的位置。扫描线每扫过一个 i 就把线段树上 lasi 的位置改为 i,这样你在 rj=i 时线段树上 [0,lj1] 的最大值就代表 [lj,rj] 中那个符合 1 情况的 i2 情况只需要将整个序列倒过来,更新 lasi,同时把询问也倒过来,进行和 1 情况相同的操作就行。3 情况扫到 i 的更新就变成了把 lasi 位上变成 (i1)(lasi+1)+1,查询就直接查 [lj,rj] 的最大值即可。

再说一下扫描线具体是怎么扫的:我们从 1n 遍历原序列,每扫到一个 i 就 update,将线段树上 lasi 位置(一般化地来说就是和 i 形成有贡献的区间的一个位置)修改为 i,表示在查询的区间包含 lasi[lasi,i] 这段区间是被包含的,可以产生贡献的。每扫到一个 rj=i 时就进行查询,把答案更新到数组对应编号中,一次这样的扫描线是 O((n+m)logn) 的。

for(int i=1,j=1;i<=n;++i){
		update(1,0,n,las[i],i); //注意这里会有-1,会涉及到0
		while(j<=m&&q[j].r==i){
			ans[q[j].id]=max(ans[q[j].id],query(1,0,n,0,q[j].l-1)-q[j].l);
			++j;
		}
	}

GSS2 - Can you answer these queries II

有参考价值的。显然不能像GSS1那样直接线段树维护前后缀最大子段和了,因为涉及到子区间,考虑能不能离线下来扫描线处理。这里有个trick:我们让线段树的每个叶节点表示以 i 为开头的最大子段和,每次在线段树上对 [lasi+1,i] 加上 ai,这样就能保证相同的数的贡献覆盖区间无交,并维护区间历史最大值。维护历史最大值是很容易感性理解的,你还需要同时维护历史最大的 tag。

P9990 Ynoi Easy Round 2023 TEST_90

因为涉及到子区间个数计数,也就是需要考虑到所有子区间。一个trick是考虑扫描线记录线段树上的历史版本和,很好感性理解,因为我们扫描线是在不断加上新的元素的贡献,相当于将区间右端点的取值范围扩展到了当前的 i,所以所有区间的答案之和就是所有历史版本之和。

然后考虑对每个数考虑他的贡献。显然他能影响到的区间和前几道题一样还是 [lasi+1,i],而他的贡献相当于是将所有区间答案的奇偶性取反。想要统计答案还需要记录每个节点上答案为 0/1区间个数被统计的次数,记为 t0,t1,这样每个区间的答案就是两个 tag 乘上对应答案的子区间个数。注意你每次修改都要对 [1,n] 额外修改一次 t[1].t1++,t[1].ans+=t[1].sum1;,这样这个 t1 就可以下传到整颗线段树。

CF522D

扫描线板题,独立秒了欸。将 las[i] 修改成 ilas[i] 然后查区间最小值就做完了。

posted @   和蜀玩  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示