【题解】Solution Set - NOIP2024模拟赛4

【题解】Solution Set - NOIP2024模拟赛4

https://www.becoder.com.cn/contest/5501


T2 沉默乐团

https://www.becoder.com.cn/submission/2593352


T3 深黯「军团」

记录一下考场思路:

首先对于长度为 \(n\) 所有排列,按顺序求出她的逆序对数量。然后找到了规律。

后面基于此,写出来可以根据长度和康托展开的编号求出逆序对前缀和的函数。

按道理这样就可解了,但是康托展开的结果太大了,达到了 \(500000!\) 的量级,实际上根本无法直接处理。

所以就完全破产了。

https://www.becoder.com.cn/submission/2593271

由于 \(k\) 很小,所以后面就整了一个可以求前缀后缀和的东西,然后算了一下。


一个结论:

所有 \(1\sim n\) 的排列的逆序对之和为 \(n!\dfrac {n(n-1)}4\)

(其实这个就是当时考场代码求的 \(f_n\) 数组。

但是问题还是求一个排列的前缀逆序对之和。

首先需要拆成 \(n\) 位,每位的贡献就是后面比她小的数的个数,设成一个序列 \(b\)。然后有两种做法:

  1. 用康托展开来理解,那么这相当于一个不等进制数(想到过拆位算贡献,但是这个东西没见过啊😰):从右往左进制为 \(i\),位权为 \(i!\)。这个数转成十进制就是康托展开的值,数位之和就是逆序对数。然后跑数位 dp 就行。
  2. 直接模拟,每次就是该数 \(+1\),也就是找到末尾最长的一段 \(0\sim i\),然后全改成 \(0\)\(i+1\)\(+1\),考虑到 \(20!>10^{18}\),我们对于每一位算她的贡献就可以了。

后面代码改的是数位 dp。


posted @ 2024-09-01 11:45  CloudWings  阅读(11)  评论(0编辑  收藏  举报