loj2765 - 冒泡排序 题解

Portal

根据结论,冒泡排序交换次数就是逆序对数。

考虑交换 \(l,r\),那么逆序对数会减少一些。显然只需要考虑 \(l/r\)\([l,r]\) 内部元素组成的逆序对的增减,\((l,r)\) 还要去重,不难列出逆序对增加个数(就是减少个数的相反数)的式子:

\[-grt(l,r,a_r)+lss(l,r,a_r)-lss(l,r-1,a_l)+grt(l,r-1,a_l) \]

前缀和展开:

\[\begin{aligned}-Grt(r,a_r)+Grt(l-1,a_r)&+Lss(r,a_r)-Lss(l-1,a_r)\\-Lss(r-1,a_l)+Lss(l-1,a_l)&+Grt(r-1,a_l)-Grt(l-1,a_l)\end{aligned} \]

计算使得这个式子最小的 \((l,r)\)。考虑惯用套路:从左到右扫 \(r\),然后维护当前 \(r\) 情况下的基于 \(l\) 的式子序列。我们令这 \(8\) 项分别 \((1)\sim (8)\),则不难发现 \((1),(3),(6),(8)\) 仅关于一个变量,脚趾头都能维护。\((5),(7)\) 可以在 \(r\) 上升的过程中,维护一个基于(离散化后的)值域的线段树区间加。那么 \((2),(4)\) 呢?似乎不太可做了。

这时候我们要坚定信念,认为自己的 DS 水平没问题(并不是),肯定是要什么特殊性质才能维护。显然 \(a_l>a_r\) 的时候交换才会使得那个式子为负,那么直觉告诉我们对 \(i<j(a_i>a_j)\),交换 \((i,r)\) 一定比交换 \((j,r)\) 好。其实也很好证:交换 \((i,r)\) 相当于先交换 \((j,r)\) 再交换 \((i,j)\) 再交换 \((j,r)\),而其中提及的每次交换都满足式子为负,所以 \((i,r)\) 肯定减少的更多。对 \(r\) 的讨论同理。这便是一个 nice 的性质了。

这样子有效的 \(l,r\) 从左到右分别都是递增的。于是 \((5),(7)\) 的维护中基于值域和基于下标便是等价的了,只需要二分找到对应下标。那么 \((2),(4)\) 呢?注意到 \(a_r\) 单调增,于是任意一个数是否对 \((2),(4)\) 有贡献(若有贡献那么显然贡献的是一个后缀)也是关于时间单调的,装个桶到时候添加 / 删除一下即可。

式子很难推,代码很难写。

posted @ 2020-11-15 15:08  ycx060617  阅读(161)  评论(1编辑  收藏  举报