CF1830E Bully Sort
我永远喜欢数据结构。
对于一个排列 \(P_1\sim P_n\),定义 \(f(P)\) 为重复执行以下操作直至将其升序排序的操作次数:
找到一个位置 \(i\),使得其是满足 \(P_i\ne i\) 的位置中 \(P_i\) 最大的那个位置。
找到一个位置 \(j\),使得其是满足 \(i<j\) 的位置中 \(P_j\) 最小的那个位置。
交换 \(P_i,P_j\)。
可以证明能够在有限次操作内将 \(P\) 升序排序。
给出一个排列 \(p_1\sim p_n\),有 \(q\) 次操作,每次交换 \(p_x,p_y\),求交换后排列的 \(f(p)\)。操作之间不独立。
\(n\le 5\times 10^5\),\(q\le 5\times 10^4\)。
tags:
-
\(\text{data structures}\)
-
\(\text{math}\)
-
\(\color{maroon}*3500\)
一句话题解:人类智慧,三维偏序。
考虑如何求 \(f(p)\)。
对于一个排列 \(p_1\sim p_n\),记 \(pos_i\) 表示 \(p_{pos_i}=i\)。设 \(F(p)=\sum\limits_{i=1}^n |i-p_i|,G(p)=\sum\limits_{1\le i<j\le n}[p_i>p_j]\)。由于最终排列有序,因此最终 \(F(p)=G(p)=0\)。
我们发现,在排列无序时,操作中 \(i\) 一定满足,\(\forall\,k\in(p_i,n],{pos_k}=k\) 且 \(i<p_i\)。前者是因为不存在更大的数,后者是因为 \(p_i\ne i\)。
我们可以得到以下几条性质:
-
\(p_{p_i}<p_i, p_{p_i}\ge p_j \Rightarrow p_j<p_i\)。
-
\(\forall\,k\in(p_i,n],{pos_k}=k\Rightarrow j\le p_i\Rightarrow \forall \,k\in(i,j),p_i>p_k>p_j\)。
由于交换,则 \((i,j)\) 内数原本和 \(p_i,p_j\) 产生的逆序对,都会消失。且 \(p_i,p_j\) 产生的逆序对也会消失。因此 \(G(p)\) 的减量为 \(2(j-i)-1\)。
考虑 \(F(p)\) 的减量,即 \(|i-p_i|+|j-p_j|-|i-p_j|-|j-p_i|\)。
我们发现 \(p_j\le i\)。因为 \(p_j\) 是 \(p_{i+1}\sim p_n\) 中的最小值,可以根据鸽巢原理 / 反证证明。
这样就可以拆绝对值了:
设 \(g_{F/G}(i)\) 为 \(f(p)\) 中第 \(i\) 次交换对 \(F(p)/G(p)\) 的减量。则通过上述推导我们已经得到了 \(\forall\,i\in[1,f(p)],g_{F}(i)=g_G(i)+1\)。
可以得到:
带入等量关系求解可得 \(f(p)=F(p)-G(p)\)。
\(F(p)\) 容易维护,\(G(p)\) 就是动态逆序对,使用树状数组套平衡树维护,每次加上变化量即可。
时间复杂度为 \(\mathcal{O}(n\log n+q\log^2 n)\),空间复杂度为 \(\mathcal{O}(n\log n)\)。
提交记录(\(\color{limegreen} \bf Accepted\),\(\bf 4.12\,\text{s}\,/\,262.56\,\text{MB}\),含代码)