偏序问题

偏序问题

前言

2025.02.26 似乎有人看过这个了,建议不要看,因为我自己都看不懂,又长又臭还没有什么有用的东西。当然你可以当做乐子来看。

如何寻找降维的突破口?(大多是三维降二维)

瞪眼或者乱试?不如经验来得快!

经典的二位偏序是给定若干二维元素 \((a_i,b_i)\),问对于每个 \((a_i,b_i)\) 有多少个 \(j\) 满足 \(a_i<a_j \land b_i<b_j\)


【2021提高组十连测day7】a 经典二位偏序。要维护的信息比较多。

三维偏序就是三维元素 \((a_i,b_i,c_i)\),计数 \(a_i<a_j \land b_i<b_j \land c_i<c_j\)

减少特征数量

但是比如 P11364 [NOIP2024] 树上查询这题,我们有元素 \((x_i,y_i,d_i)\) 和元素 \((l_i,r_i,k_i)\),其中后者是询问。

这题不是计数,而是求最优性问题,不过没什么影响。

\[y_i-x_i+1 \ge k \land \begin{cases} y_i \le r \land y_i - l +1 \ge k & (y_i \le r)\\ y_i > r \land r-x_i+1 \ge k & (y_i > r) \end{cases} \]

这道题由两个逻辑或链接的偏序关系,对于每个偏序关系,恰好可以转化成二位偏序,这里的恰好其实并不是 ad-hoc 的,其实是把三个特征的其中两个通过运算符变成一个特征,从而转化成二位偏序问题,可以根据以下步骤找出:

  1. 按元素移项:把两个元素移到不等式不同边。
  2. 合并同类项:把具有相同特征的元素的合并。如果合并后每个元素都只有两个特征了,基本上说明可以转化成二位偏序问题。
  3. 扫描线主元选择:选择简洁的偏序用于扫描,复杂的偏序用数据结构维护。一般扫描询问的某个特征,将符合这个偏序的数据按照另一个特征存到数据结构里,按照另一个偏序,根据询问的另一个特征查询。

如上面的式子可以化为以下式子,将前面的偏序用于扫描:

其中式子 \(1\) 是询问包含了数据,需要数据结构支持区间查询或者维护的信息满足可差分性。显然这里是前者。

\[\begin{cases} y_i-x_i \ge k-1 \land k+l-1 \le y_i \le r & (1)\\ y_i>r \land x_i \le r-k+1 & (2) \end{cases} \]


SS241113C. 数据结构 (struct) 这是一个二维数点。

\[pos_l < l \le mn_{c+1} \land mx_{c+1} \le r < pos_r \]

通过合并同类项,得到两个特征数为 \(2\) 的元素 \(((pos_l,mn),(mx,pos_r)),(l,r)\),后者是询问。

扫描主元选第一个偏序或者第二个偏序都一样,我们选中第二个,第一个偏序用数据结构维护。

  • 扫到 \(mx\) 的时候,说明后面的 \(r\) 都可以合法地享受这个 \(mx\) 对应的元素的贡献,在数据结构的 \((pos_l,mn]\) 加入贡献。
  • 扫到 \(r\) 的时候,在数据结构查询 \(l\)
  • 扫到 \(pos_r\) 的时候,说明后面的 \(r\) 都不可以享受这个 \(pos_r\) 对应的元素的贡献,在数据结构的 \((pos_l,mn]\) 删除贡献。

这里扫描线主元是数据包含了询问,需要数据结构支持撤销,这里是维护的信息存在逆操作。另一个偏序也是数据包含了询问,需要数据结构支持区间修改。

容斥

而像 24ab-day8 洄游这题,你有元素 \((l_i,r_i,r_i-l_i)\) 和元素 \((L_i,R_i,K_i)\),后者是询问,要求:

\[l_i \ge L_j \land r_i \le R_j \land r_i-l_i \ge K_j \]

这看起来是一个三维偏序。

发现数据的第三个特征是前两个特征运算生成的,所以可以尝试转二位偏序。最简单的步骤应该是画图容斥,似乎直接想很难做。容斥详见上面题目链接。

尝试取反一些偏序的符号,使得某个偏序必然成立/不成立。其实就是找出所有的造成空集的偏序。把这些空偏序在画的图上面叉掉,然后容斥。

如这里,我们特判掉 \(R-L < K\) 的情况之后,当 \(l<L \land r>R\) 的时候,\(r-l\ge K\) 一定成立。

扫描数据(似乎不属于降维)

SS241007B. 逆序对(inverse) 数据是 \((x_i,y_i)\),询问是 \(((x_j,x_k),(y_j,y_k))\)

缩小有效询问范围(一般在最优解问题中?)。

\[x_j \le x_i \le x_k \land y_j \le y_i \le y_k \]

询问的函数是 \(\sum f(x_i,y_i)=1\)。要求所有询问的最大值。

都是询问包含数据。而且信息可以差分,因为要求极值。

询问有 \(O(n^2)\) 个,数据有 \(O(n)\) 个。

如果询问少就可以直接遇到数据修改数据结构,遇到询问查询数据结构。但是询问过多,无法操作。

询问太多,可以把操作反过来。即遇到询问插入数据结构,遇到数据修改数据结构。

但是你如何维护 \(O(n^2)\) 个类似于数据点卷积的询问?我不会。

于是观察发现不是所有询问都是有用的。只有以前缀最大值为左上端点,后缀最小值为右下端点的询问才有用。不难证明其他情况一定更不优。

于是询问变成两个数列的点:\(\{(ax_j,ay_j)\},\{(bx_j,by_j)\}\),有 \(O(n^2)\) 个询问 \(\{(ax_j,ay_j), (bx_k,by_k)\}\)。询问数量级没有减少,但是询问变得更有性质了。

如何维护这样优美的询问?

由于询问的特殊性质,即 \(x_j \le x_{j+1}, y_j \le y_{j+1}\),对于 \(a,b\) 均是如此。

满足偏序的询问刚好是一个矩形!具体地,以 \(j\)\(x\) 轴,\(k\)\(y\) 轴建立笛卡尔坐标系,原偏序可以转化为:

\[lx \le j \le rx \land ly \le k \le ry \]

其中 \(lx,rx,ly,ry\) 是数据决定的,即数据的特征。

现在变成有 \(O(n)\) 个数据 \(((lx_i,rx_i),(ly_i,ry_i))\),有 \(O(n^2)\) 个询问 \((j,k)\)

很经典啊。

数据是可以直接差分的,变成单个不等号的二维偏序。

扫描 \(x\) 轴,遇到数据使用数据结构以 \(y\) 为下标进行区间修改。可以差分成前缀修改。遇到询问查询最大询问。


SS241120D. 周长(perimeter)

简化一下题意,就是给你 \(n\) 个点,求最大周长的矩形,满足矩形内部没有严格包含的点(在边界不算包含),问最大周长是多少。

\(n\) 个数据 \((x_i,y_i)\),有 \(O(n^2)\) 个询问 \(((x_j,x_j'),(y_j,y_j'))\)(分别表示询问的矩形的最小和最大角落的坐标)。

(假设已经做了离散化)

偏序是:

\[x_j < x_i < x_j' \land y_j < y_i < y_j' \]

都是询问包含数据。而且信息可以差分。

合法的(满足函数关系)是满足偏序的数据个数为 \(0\) 的询问。求合法询问的最大贡献(贡献为矩形周长,不重要)。

和上题遇到了几乎一样的困难。这告诉我们需要寻找其他性质,否则不可做。

这里的询问也很优美,但是如果使用数据更新询问,就很不优美,因为询问和数据都不可差分。

可以类似上一题变成数据可差分吗?排除无用的询问后,能找到的性质就是询问的四个边界都一定有数据点。这并不是什么有用的性质。

发现答案下界是 \(2\max(n,m)+2\)。构造就是选择 \(n \times 1\) 或者 \(1 \times m\) 的矩形。

一种正常人类的思考思路是对于这样的矩形,想到分治。

分治 \(mid\) 的时候,要求矩形必须跨过 \(mid\)

一般都是枚举下界,维护最优上界,所以要求左右边界是唯一确定的。不难发现这里确定上下界和中线之后左右边界是唯一确定的。

下界往下移动的时候,上界答案(每个上界对应的左右边界)可以进行全局取 \(\min\) 和单点修改来维护。

然后发现上面的性质可以保证答案矩形一定跨过 \(x\) 轴的中线或者 \(y\) 轴的中线。所以只需要分治一次。

混合经验

简单的二维降一维:P9108 [PA2020] Malowanie płotu 这题要数区间交非空的偏序,即 \([l,r] \cap [l',r'] \neq \emptyset\)。前者是询问。

\[\begin{cases} r\ge l' \land r\le r' & (r\le r')\\ l\le r' \land r > r' & (r > r') \end{cases} \]

这是二维偏序。合并同类项就是一维偏序了。但是第一个偏序会出现只能扫描数据,维护询问的问题,这样不方便后面优化。发现当 \(r<l'\) 的时候 \(r\le r'\) 一定成立,于是容斥。于是就有了扫描询问的一维偏序了。

插入-标记-回收算法

lxl 讲的。

用于做复合函数问题:有 \(n\) 组数据 \(\{x_i\}\),有一个函数 \(f(x)\) ,有 \(q\) 次询问 \((s,l,r)\),每次询问问一个初始状态 \(s\) 在对所有 \(i \in [l,r]\),执行 \(s=f(s,x_i)\),最终得到的 \(s\) 的值。

方法是扫描 \(l,r,i\),遇到 \(l\) 的时候在数据结构里插入一个 \(s\) 以及它的询问 \(id\),对每个扫描的 \(x_i\),将数据结构所有的状态执行全局函数操作。遇到 \(r\) 的时候将对应状态取出数据结构并输出。

本质上是有两种只有一组特征的元素,\((l,r,s)\)\((i,x_i)\),前者是询问。偏序是 \(l \le i \le r\)

因为函数不满足可差分性,所以只能这么做了。

即扫描这一维,遇到询问左端点插入数据结构,遇到数据修改数据结构,遇到询问右端点查询数据结构。


chesed

函数 \(f(s,x_i) = \max(s,x_i-s)\)

二次偏序问题

二次是指有三个元素。


QOJ 2266. Colorful Rectangle 二次二维偏序。降一次二维偏序。

颜色分别是 \(0,1,2\) 的点若干个。是最优解问题。为了方便求答案时不用考虑取 \(\max\) 的问题,我们把题目分成两类偏序。求满足以下偏序关系的最小 \(f(x_0,y_0,x_1,y_1,x_2,y_2)\)。(该函数不影响偏序的做法)

  1. \(x_0 < x_1 < x_2 \land y_1 < y_2 < y_0\)
  2. \(x_0 \le x_1 \le x_2 \land y_0 \le y_1 \le y_2\)

容易发现第二种可以拆成两个不相干的二维偏序:\(x_0<x_1\land y_0<y_1,x_1<x_2\land y_1<y_2\)。两个二维偏序之间没有互相影响。

第一种不能这么拆。考虑扫描 \(x\) 这一维,把其中两种元素合并成一种元素,即数据,第三种元素作为询问。遇到数据的时候修改数据结构,遇到询问查询数据结构。所以先扫描数据再扫到询问。可以设 \(0,1\) 是数据,\(2\) 是询问。

这样的好处是数据之间只剩下时间戳的偏序关系,\(y\) 的偏序关系被拆成了不同的互不影响的偏序:\(y_1<y_2,y_0>y_2\)

时间戳的偏序关系在维护数据结构注意下放标记的顺序即可。

实际上是转化成了 \(O(n^2)\) 个数据,\(O(n)\) 个询问。第一维只有一个等号,第二维是两个等号的数据包含询问类型。

但是数据过多,无法对每个数据进行操作。

因为这并不是普通的离散数据,所以有优化空间。数据是由两类 \(O(n)\) 数量的特征按照一维一个等号的偏序卷起来得到的。


SS250206D. 怒气冲天(rectangle) 二次二维偏序,不会做。

【总结】偏序问题如何根据特征的偏序关系看出做法

首先把可差分的都差分了。

  • 扫描的特征维:
    • 一个不等号:扫描方向满足数据比询问先扫到,遇到数据修改,遇到询问查询。或者扫描方向满足询问比数据先扫到,遇到询问插入,遇到数据修改,一般这么做是因为最后只需要得到所有询问的答案的极值。
    • 两个不等号:
      • 询问包含数据:参考 lxl 的《插入-标记-回收》算法,数据结构支持插入-标记-回收。
      • 数据包含询问:数据结构可撤销。
  • 数据结构维护的特征维(二维才有):
    • 一个不等号:树状数组即可。
    • 两个不等号:
      • 询问包含数据:数据结构支持单点修改,区间查询。
      • 数据包含询问:数据结构支持区间修改,单点查询。
posted @ 2025-02-06 21:59  wing_heart  阅读(86)  评论(1)    收藏  举报