新年好,各位。
P7054 [NWRRC2015] Graph
我们假设 \(k=0\),那么我们求最小字典序就是通过一个小根堆维护当前入度为 \(0\) 的点,每次取出最小。
那么如果 \(k\neq 0\),我们就可以阻止“取出最小”这个过程,也就是给当前最小这个点一个入边。
我们重复给当前最小点一个入边的操作可以贪心地使最小字典序最大。
但是入边是从哪里连过来的很难处理。我们考虑先不给这个点分配入边。
直到必须要用到上述点的时候,我们让其连向拓扑序的上一位即可。所以我们用大根堆维护这些点。
所以当小根堆大小 \(\ge 2\) 的时候,取出最小的并将其加入大根堆。
注意小根堆大小为 \(1\) 的时候就无法给其分配入边了,否则一定成环。
不过我们可以考虑取出一个大根堆里的元素出来,连上上一个,并让当前小根堆的元素连向他。
若小根堆大小为 \(0\),那么我们就要取出大根堆的元素,每次弹堆顶即可。
AGC001F Wide Swap
首先考虑令 \(Q=P^{-1}\),即 \(P_{Q_i}=i\),\(Q_i\) 相当于是在排列 \(P\) 中 \(i\) 的位置。
那么交换的条件就相当于交换相邻的 \(Q_{i},Q_{i+1}\),且他们差的绝对值 \(\ge K\),转化为熟悉的模型。
我们要想 \(P\) 的字典序最小,就相当于将 \(Q\) 排序。
注意到,重复交换 \(Q_{i}-Q_{i+1}\ge K\) 的两位置过后,每次都是使其更优,重复操作直到 \(Q_i-Q_{i+1}<K\)。
注意,我们去除了绝对值,相当于每次都减少了一个逆序对,与排序的本质相同。
那么最后 \(Q\) 相当于排好序。并且有且仅有一种排好序的方式,此时是最优的。可以关注 \(K=1\) 的情况。
证明有且仅有一种最优,假设存在另一种,那么肯定存在某对数相对位置改变,
而操作可逆,所以这两种状态是可达的,那么这对数是可以调换顺序的,所以只有一种最优。
排序的话,如果是 \(O(n^2)\) 那么可以直接类比冒泡排序。优化考虑换成归并排序。
相当于合并两段数,这两段数都满足 \(Q_i-Q_{i+1}<K\),并且各自内部顺序不会再改变。
我们只需要解决当前数是填左边的还是右边的问题。如果右边更优那么其就得交换到左边这里来。
设左边是第 \(i\) 个数,右边是第 \(j\) 个数,\(R_j\) 要交换到 \(L_i\) 前面,那么 \(L_{i,i+1\dots mid}-R_j\ge K\)。
所以我们只需要求一个后缀最小值即可。于是归并排序完成。
联想到排序确实很厉害。但是有没有简单的办法呢?
考虑相对位置不变的数,他们之间连有向边,跑拓扑排序即可。用线段树优化建图。像 AGC010E。