TB5 分治+半平面范围查询修改问题
因为本人在 whk,所以写的很慢。
受篇幅约束,本人主要讲解实现,关于 TB5 分治在该问题约束下最优性的证明请参考 lxl 原 PPT。
参考自 清华大学 李欣隆 的 PPT《范围修改查询问题》。
请注意,TB5 分治最优秀的地方在于操作次数的最优化,关于时间复杂度其实不见得是很好的做法。
目录
-
信息的基本分类及范围的概念
-
双半群模型——范围修改查询问题的抽象数据结构模型
-
平面图点定位
-
TB5 分治——最优操作次数离线范围修改查询算法
-
半平面模型及其例题
信息的基本分类及范围的概念
半群
给定一个集合
对于该运算满足结合律:
幺半群
给定一个集合
对于该运算满足结合律:
满足幺元存在使得:
交换半群
给定一个集合
对于该运算满足结合律:
对于该运算满足交换律:
范围
常见的范围有序列区间,树简单路径,二维平面矩形,高维正交范围,半平面范围,圆范围。
我们一般理解成对于进行修改和查询的信息的限制。
双半群模型——范围修改查询问题的抽象数据结构模型
受不了了,不想自己写。
直接贺一下 lxl PPT 里的图。
还需要注意的是对于
我们称这样的模型为双半群模型。
平面图点定位
我应该会讲一下这玩意儿。因为我现在还不会。
网上资料学不懂,等我再复习一下计算几何。
平面图点定位
TB5 分治——最优操作次数离线范围修改查询算法
其实最重要的,这玩意儿严格以上来说应该是最优操作次数。
等价类
我们先来看一个简单的题,对于长为
这个太简单了,练习时长两年半的学生都会用线段树做
但是如果
那么在一定的操作下能被划分成满足“时时刻刻都是被整体修改查询”的信息集合我们可以称其为等价类。
我们记
显然对于
在进行划分的时候我们一个想法是尽量能少划分就少划分以达成减少数据结构需要维护的信息数量。
不难发现操作越多,划分的越细。
从 lxl 的 PPT 里面扒了个例子下来,如图,划分的范围是双曲线,相应的等价类在图中已标明。
动态有根森林
下文假设所有对于分治数据结构上节点的信息修改都是
联想到我们树形分治数据结构的本质思想:叶子层节点是我们实际需要维护的信息,非叶子层节点的建立是为了方便修改和查询而建立的辅助节点。
我们常用且在大多数时比较高效的数据结构:线段树。它的一些性质:
-
符合树形分治数据结构的本质思想;
-
每个节点上有子树中所包含的叶子节点信息和,以及负责下传的标记;
-
二叉;
-
树高
O(\log n) ; -
节点数量级为
O(n) 。
所以我们考虑维护这样一个动态有根森林,满足:
-
动态森林的每棵树都对应一个等价类;
-
符合分治树形分治数据结构的本质思想;
-
每个节点上有子树中所包含的叶子节点信息和,以及负责下传的标记;
-
对于非叶子节点的叉数不固定;
-
节点数量级为
O(n) 。
我们贪心地想要让等价类的数量更少,即让我们的划分符合等价类定义的情况下划分的更粗点。
如何在加操作和删操作时维护动态有根森林
我们的想法很直接,动态地维护加点和删点。
离线所有操作,记操作序列为
在维护时由于合并等价类看起来更容易些,即删操作更容易些,所以考虑线段树分治,我们维护出最开始的操作
每次走到线段树上一个节点
当走到叶子节点时,不难发现只存在
从
从
你会发现上述的过程无异于套了个分治然后暴力维护,太优雅了。但是时间复杂度看起来很爆炸啊!!!
下文会证明这一系列操作的时间复杂度,已知的是只和范围的维度有关系。
区域数
我们暂且先假设“找到需要合并的等价类树根”是
定义离散函数
同时定义离散函数
以区间加区间和举例,在从
显然回退时间复杂度与合并时间复杂度是同数量级的,所以可以默认从一个父亲转移到另一个子节点单次涉及到的等价类合并数量级为
由此我们对该分治方法得到一个关于时间复杂度的计算方法:
代入主定理,不难得到最后的时间复杂度为
关于“找到需要合并的等价类树根”的方法
对于二维以上的问题我不会。
对于二维可以通过平面图点定位的方法,对于“找到需要合并的等价类树根”可以多消耗一只
但是对于一些一维问题如区间加区间和貌似是可以有更精巧的预处理方法。没必要强加一只
upd on 2023/1/11
和超人学者进行了深入交流,爷会了!
我们通常认为,我们采用如下的方法,进行“从一层节点的等价类向另一层的等价类建立相邻层映射”的过程:
-
将上一层的等价类视为可被修改的信息节点,从每个等价类内选择一个代表元执行操作;
-
通过可以实现的平凡数据结构,利用 hash,将下一层的修改操作对信息节点群执行范围加;
-
最后对每个点求和的过程,我们的问题从“范围修改查询”转化成了“范围修改,单点查询”,问了下 ccz,这样的问题转化大多数时会对问题降维,比如 P6109。
-
这里举几个例子。区间加区间和的通用方式就是使用区间加区间和线段树;矩形加矩形和的通用方法是扫描线加线段树;半平面修改查询的通用方法是四分树套旋转扫描线。
半平面修改查询通用方法
这个很重要。
我们建立的四分树不是传统意义上的二维线段树,我们假设我们就做半平面修改半平面查询,我们每次将一个平面按照点集大小均匀划分成四等份,任意一个半平面只会递归入至多三个平面,那么直接做“半平面修改查询”问题,时间复杂度
如果是“半平面修改,单点查询”我们将底层换成旋转扫描线即可,钦定当四分树上区域内的点集大小小于等于
设当前等价类的个数为
四分树:
旋转扫描线:
平衡一下就可以做到
实例代码
P3372
线段树区间加区间和板子,初始化预处理出来底层等价类,每次选择等价类中的一个点设为代表然后用 hash 对每层“范围修改,单点查询”,开栈回撤即可。
事实上可以通过合并离散化端点的方式来合并等价类,时间复杂度就可以砍一个
link
范围查询和范围修改查询区别
只有查询基本上时间复杂度和操作数有关;而范围修改查询就不一样。
一个好的例子是区间加区间和如果操作数为
实际应用
[CTS2021]测测你的半平面修改查询
暂时没被公开,虽然在 PPT 内算是被公开了但是还是先不讲了。
其实就是将上面的二维问题换成了半平面。
卡 KDT 修改次数的常
这个是矩形操作的哈。
- [Ynoi2007] TB5x
具体讲解,咕咕咕。
萌新的眼神.jpg。
半平面模型及其例题
这个在近几年的 Ynoi 中出现还是有那么几道。
主要思想有沿用等价类思想操作分块后旋转扫描线,以及基于随机撒点的半平面莫队等等。
随机数据半平面数点
由于点在平面上均匀随机分布,我们直接将平面剖成
旋转扫描线解决半平面问题
link