ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

# $\texttt{Sol. Luogu P6186}$ [NOI online #1 提高] 冒泡排序

2022-06-29 21:02:12  阅读:171  来源: 互联网

标签:P6186 NOI 交换 个数 冒泡排序 前缀 text 逆序


\(\texttt{Sol. Luogu P6186}\) [NOI online #1 提高] 冒泡排序

太毒瘤啦!!!果然是我太菜(水)了......

题目描述

给定一个 \(1 ∼ n\) 的排列 \(p_i\),接下来有 \(m\) 次操作,操作共两种:

  1. 交换操作:给定 \(x\),将当前排列中的第 \(x\) 个数与第 \(x+1\) 个数交换位置。
  2. 询问操作:给定 \(k\),请你求出当前排列经过 \(k\) 轮冒泡排序后的逆序对个数。
    对一个长度为 \(n\) 的排列 \(p_i\) 进行一轮冒泡排序的伪代码如下:
for i = 1 to n-1:
  if p[i] > p[i + 1]:
    swap(p[i], p[i + 1])

思路:

很显然,我们必须先思考有关冒泡排序的本质,获得相关性质,才能继续做题。

所以这个本质是什么呢?

干想了一会,啥也没想出来,就举个例子:

\(\text{4 3 5 2 1}\to\text{3 4 2 1 5}\)

大概能发现,一个数能往后交换,仅当它左边已经没有了比他大的数。这样,它才能往后交换,去“消灭”逆序对。开始时,一个数的前面有多少个大于它的数,它就要交换多少次,本轮就不能发挥它的作用。当前轮有 \(x\) 个能交换的数,就有 \(n-x\) 个逆序对被消灭。一个数的前面有 \(t\) 个比他大的数,这个数在 \(t+1\) 轮排序才会往后交换。

我们要求的,是冒泡排序进行 \(k\) 轮后逆序对的个数,那就把不修改的情况预处理出来,再考虑修改对答案带来的影响。

记 \(a[i]\) 为原数列, \(b[i]\) 为 \(a[i]\) 前面有多少个数比他大。将 \(\{b\}\) 丢进一个桶里(\(h\)),在这个桶上建立树状数组求前缀(因为对于\(b\)中的非零数来说每轮被交换一次,每轮是要\(-1\)的,故当前 \(b\) 中 \(0\) 的个数再拿 \(n\) 减就是本轮逆序对减少的数量,所以是求前缀)就可以预处理出第 \(i\) 轮减少的逆序对个数。

然后就是考虑修改带来的影响。

容易发现,相邻的两项交换,对整体逆序对个数的影响只能是 \(+1(a_x<a_{x+1})\) 或 \(-1(a_x>a_{x+1})\) 。以 \(+1\) 为例,这个变换在序列 \(\{b\}\) 中的影响就是 \(b_{x+1}+1\) 。在 \(b_{x+1}\) 这一项 \(+1\) 后,即 \(b_{x+1}\) 执行冒泡后,剩余部分和未交换的结果就是一样的了。

$$\left[\begin{matrix}a:&4&3&5&2&1\ b:&0&1&0&3&4\ h:&2&1&0&1&1\end{matrix}\right]\ \overset{\text{Exchanging a[2]&a[3]}}{\longrightarrow} \ \ \left[\begin{matrix}a:&4&5&3&2&1\ b:&0&0&2&3&4\ h:&2&0&1&1&1\end{matrix}\right]$$

根据“当前轮有 \(x\) 个能交换的数,就有 \(n-x\) 个逆序对被消灭”这句话,我们用 \(n(=5)\) 依次减 \(\{h\}\) 的前缀和,得到每轮减少的逆序对个数:

原来:\([2,1,0,1,1]\to[3,2,2,1,0]\)

之后:\([2,0,1,1,1]\to[3,3,2,1,0]\)

对这个新得出来的序列再做前缀和。容易发现,做完前缀和后交换操作可以很方便维护。当然,因为我们要的是 \(k\) 趟冒泡排序后的结果,所以这个答案序列是要不断单点更新 + 求前缀和的,用树状数组维护。

(大概是对的吧...?)代码明天写。

为什么想不出来?\(\huge\text{思维浅了!}\) 或者是 \(\huge\text{模拟能力不够?}\)

标签:P6186,NOI,交换,个数,冒泡排序,前缀,text,逆序
来源: https://www.cnblogs.com/Doge297778/p/16424897.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有