#L2719. 「NOI2018」冒泡排序
「NOI2018」冒泡排序
题目描述
最近,小 S 对冒泡排序产生了浓厚的兴趣。为了问题简单,小 S 只研究对 到 的排列的冒泡排序。
下面是对冒泡排序的算法描述。
输入:一个长度为 的排列
输出: 排序后的结果。
for i = 1 to n do
for j = 1 to n - 1 do
if (p[j] > p[j + 1])
交换 p[j] 与 p[j + 1] 的值
冒泡排序的交换次数被定义为交换过程的执行次数。可以证明交换次数的一个下界是 ,其中 是排列 中第 个位置的数字。如果你对证明感兴趣,可以看提示。
小 S 开始专注于研究长度为 的排列中,满足交换次数 的排列(在后文中,为了方便,我们把所有这样的排列叫「好」的排列)。他进一步想,这样的排列到底多不多?它们分布的密不密集?
小 S 想要对于一个给定的长度为 的排列 ,计算字典序严格大于 的「好」的排列个数。但是他不会做,于是求助于你,希望你帮他解决这个问题,考虑到答案可能会很大,因此只需输出答案对 取模的结果。
输入格式
从文件 inverse.in 读入数据。
输入第一行包含一个正整数 ,表示数据组数。
对于每组数据,第一行有一个正整数 ,保证 。
接下来一行会输入 个正整数,对应于题目描述中的 ,保证输入的是一个 到 的排列。
输出格式
输出到文件 inverse.out 中。
输出共 行,每行一个整数。
对于每组数据,输出一个整数,表示字典序严格大于 的「好」的排列个数对 取模的结果。
样例
样例 1
输入:
1
3
1 3 2
输出:
3
解释:字典序比 大的排列中,除了 以外都是「好」的排列,故答案为 。
样例 2
输入:
1
4
1 4 2 3
输出:
9
数据范围与提示
下面是对本题每个测试点的输入规模的说明。
对于所有数据,均满足 (样例可能不满足)。
记 表示每组数据中 的最大值, 表示所有数据的 的和。
| 测试点 | 特殊性质 | ||
|---|---|---|---|
| 10 | 18 | 无 | |
| 11 | |||
| 12 | 122 | 700 | |
| 13 | 144 | 无 | |
| 14 | 166 | ||
| 15 | 200 | ||
| 16 | 233 | ||
| 17 | 777 | 4000 | |
| 18 | 888 | 无 | |
| 19 | 933 | ||
| 20 | 1000 | ||
| 21 | 266666 | 2000000 | |
| 22 | 333333 | 无 | |
| 23 | 444444 | ||
| 24 | 555555 | ||
| 25 | 600000 |
提示
下面是对交换次数下界是 的证明。
排序本质上就是数字的移动,因此排序的交换次数应当可以用数字移动的总距离来描述。对于第 个位置,假设在初始排列中,这个位置上的数字是 ,那么我们需要将这个数字移动到第 个位置上,移动的距离是 。从而移动的总距离就是 ,而冒泡排序每次会交换两个相邻的数字,每次交换可以使移动的总距离至多减少 。因此 是冒泡排序的交换次数的下界。
并不是所有的排列都达到了下界,比如在 的时候,考虑排列 ,这个排列进行冒泡排序以后的交换次数是 ,但是 只有 。