题解:AT_arc187_c [ARC187C] 1 Loop Bubble Sort

Z_drj

2024-11-20 21:35:19

Solution

这个题细节有点多啊。

考虑冒泡排序的本质,就是对于一个 a_i 满足 \max\limits_{j = 1} ^ {i - 1}{a_j} < a_i 将它交换到第一个比它大的数之前。更直观的,记 pre_i = \max\limits_{j = 1} ^ i a_i,在一个坐标系上出现 (i, pre_i) 这个点。

如果一个排列建出来长这个样子,那么显然的就是对于类似 BF 的线段(即这一段所有前缀最大值相等)上面所有点会循环左移,即除开头外,其它元素向前移动 1,开头移动到结尾。

这个时候性质就足够了,可以 dp 了。

f(i, j) 表示填了前 i 个数,当前最大值为 j 的方案数。(即会出现 (i, j) 的方案数)。

转移的话,根据上述模拟的过程可以推出来,当前位置 j 要填 i 的话,要么 ji 开头的段的结尾;要么就是 i 不是某一段开头,且 j + 1i

cnt_j 表示 Q[i + 1, n][1, j] 的出现次数。

根据上述过程可知,i 填的数和 Q_{i - 1} 有关。

这样就能写出 \mathcal{O}(n ^ 3) 的代码了,而每次区间加都是加的后缀,差分维护即可实现 \mathcal{O}(n ^ 2)

\texttt{Code}