偏序问题总结
这里使用一种便于理解的定义:\(n\) 维偏序关系是指对于两个 \(n\) 维的数对,其对应位置的每一项都依次满足固定的一系列大于,小于等关系,则这两个数对满足该偏序关系。本文讲解的是偏序关系计数问题。
二维偏序
二维偏序:
给定已知点对 \((x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n)\),求 \(x_j \lesseqgtr x_i\) 且 \(y_j \lesseqgtr y_i\) 的 \(a_j\) 数量。
此时的偏序关系为
最经典的一个二维偏序就是逆序对噜。回忆一下逆序对的两个条件:
-
\(j < i\)
-
\(a_j > a_i\)
发现和前面的式子一模一样!
然后就是重要的计算部分了(这里不仅仅可以求逆序对,也可以推广到所有二位偏序问题):
同时存在两个条件一定不容易维护答案,所以我们先固定一维,再用数据结构维护第二维(核心思想)。
对于逆序对问题,我们选择按照输入顺序处理,对于每一个数求桶中比他大的数的个数,累加到答案上。再将这个数放到桶里,这个东西就是单点修改前缀求和了,使用树状数组即可。
问题就在 \(O(n \log n)\) 的美好复杂度中解决了!
例题
上面说的很清楚了,注意开 ll,离散化。
在一条直线上有 \(n\) 条线段,每条线段用 \((l,r)\) 表示,求每条线段包含多少条其他的线段。
复杂度 \(O(n \log n)\) 以下。
首先知道线段 \((l_j,r_j)\) 被 \((l_i,r_i)\) 包含当且仅当存在 \(l_i \leq l_j \leq r_j \leq r_i\)。
进一步转化为偏序关系为
这里我们按照右端点升序排序,因为右端点大的一定不被包含。而由于题面里说了没有相同端点所以不用设第二关键字。
我们依旧开一个桶,里面存储前面的左端点,对于每条线段查询比当前左端点大的,查询比他小的然后小小的容斥一下即可。注意仍然需要离散化。
带权 LIS。显然板子的方程为
复杂度 \(o(n^2)\) 过不去,这里发现求东西可以写成求 \(j < i\) 且 \(h_j < h_i\) 的点中权值最大值,这显然是一个二维偏序,树状数组维护最大值即可。
两个问题十分相似,这里以∧
图腾举例说明。
首先显然问题可以转化为枚举一个点作为图腾的中间点(也就是那个尖),显然问题可以转化为求一个点左边比他小的点的数量以及右边比他小的点的数量,根据加乘原理,以该点为中心的答案即为两者乘积。最终答案为所有点答案加和。
发现就是求 $j < i \operatorname{and} a_j < a_i $ 的点的数量,以及 $j > i \operatorname{and} a_j < a_i $ 的点的数量,属于二位偏序问题,可以解决。另一种图腾同理。
三维偏序
三维偏序的离线做法为 CDQ 分治。
详见 CDQ 分治学习笔记
本文来自博客园,作者:Aurora_Borealis,转载请注明原文链接:https://www.cnblogs.com/Aurora-Borealis-Not-Found/p/17127400.html