扫描线

是很强大的东西。

难点是精确地刻画出限制。就是要找到限制的一个充要条件,然后放到二维平面上去用扫描线+DS维护。

常见构造二维平面的方式:以询问[l,r]作为(l,r);以需要维护的信息fi,j作为(i,j) etc.

正难则反

正着刻画限制不太行,就尝试刻画出不符合限制的情况,这样放到二维平面上。最后的答案形式或许是矩形的补。

这是常见+Simple的。

反演的想法

For instance,我们查[l,r]中的颜色数,先正难则反,考虑哪些颜色在[l,r]中没有出现。然后就可以先只关注一种颜色,然后[l,r]在相邻的两个位置之间的询问就没有这种颜色造成的贡献。这样的[l,r]放到平面上就是一个矩形,然后扫描线就好。

这样我们可以考虑一个元素对于询问的贡献然后扫描线。

来点例题

P1502 窗口的星星

link

由于窗户大小固定,我们以它的右上角来表示它的位置。考虑一个位置上的星星可以对哪些位置上的窗户造成贡献,发现贡献范围是一个矩形。

问题转化为:矩形加,查询所有点中的最值。于是扫描线可以做了。

区间子区间问题

首先需要刻画出子区间要满足的限制,剩下的都是套路。

fi,j表示子区间的信息,然后就考虑每个位置作为r新造成的贡献。于是f的整个平面都可以维护出来,同时使用历史和线段树维护一个前缀矩形的满足条件的信息(子区间)的个数/或者统计贡献之类的,询问一个区间[L,R]的子区间其实就是给子区间的左右端点加上了限制,LlrR,放到平面上还是矩形,于是用前缀矩形将这个差分出来就好。

来点例题

P3246 [HNOI2016] 序列

link

fl,r表示区间[l,r]的最小值,那么要求的就是lqlrqr的所有fl,r之和。将l作为横轴,r作为纵轴构造二维平面,于是所求的就是右下方一个矩形和。(l>r的部分,我们认为fl,r=0)。

如何求出每个f?只需单调栈维护一个值能够贡献的区间的左右端点。放到平面上,我们只需维护矩形加,2-side矩形和。后者可以历史和线段树。

扫Sequence维,DS时间维

特点是区间修改,单点询问。

我们每个时刻在序列上做修改或查询,可以构造以序列为横轴,时间为纵轴的二维平面。发现一次修改造成的影响范围在平面上是一个矩形。

我们用DS维护时间维,维护的是操作造成的影响。扫描线去扫序列,依次回答单点询问。

来点例题

P3863 序列

link

就是矩形加,然后在扫描线上查询一段前缀中不小于x的数有多少个。分块维护扫描线即可。

每个询问的x需要结合序列上对应的值ai算出来。注意一下t=0即初始时刻的特判。

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