Solution

观察冒泡排序的过程. 我们注意到, 每一轮的排序都会使得每个数后面比它小的数的个数减\(1\). 我们用\(f(n, m)\)表示对\(1\)到\(n\)的一个排列进行冒泡排序, 满足在不超过\(m\)轮内完成的排列数量. 易知

\[f(n, m) = \begin{cases} m! \\ m! (m + 1)^{n - m} \end{cases}
\]

我们再用\(g(n, m)\)表示对\(n\)个数的排列进行冒泡排序, 使得排序过程恰好\(m\)轮完成的排列数量, 则有\(g(n, m) = f(n, m) - f(n, m - 1)\). 我们可以预处理出对于给定的\(m\)的这两个函数的值, 通过这两个函数逐位确定序列的形态.

#include <cstdio>
#include <cctype>
#include <cstring> const int N = 20;
inline long long power(int a, int x)
{
long long res = 1;
for(; x; a *= a, x >>= 1) if(x & 1) res *= a;
return res;
}
inline long long frac(int a)
{
long long res = 1;
for(; a; -- a) res *= a;
return res;
}
int main()
{
int n, m;
long long rk;
scanf("%d%d%lld", &n, &m, &rk);
static long long f[N + 1], g[N + 1];
for(int i = 0; i <= n; ++ i) f[i] = i < m ? frac(i) : frac(m) * power(m + 1, i - m);
for(int i = 0; i <= n; ++ i) g[i] = f[i] - (i < m - 1 ? frac(i) : frac(m - 1) * power(m, i - m + 1));
static int a[N];
int flg = 0;
for(int i = 1; i <= n; ++ i)
{
for(int j = 1; j <= n - i + 1; ++ j)
{
long long cur;
if(flg || j == m + 1) cur = f[n - i]; else cur = g[n - i];
if(cur >= rk)
{
a[i] = j;
if(j == m + 1) flg = 1;
break;
}
rk -= cur;
}
}
static int rec[N + 1];
memset(rec, 0, sizeof(rec));
for(int i = 1; i <= n; ++ i)
{
int cnt = 0;
for(int j = 1; j <= n; ++ j)
{
if(rec[j] == 0) ++ cnt;
if(cnt == a[i])
{
printf("%d ", j);
rec[j] = 1;
break;
}
}
}
}

2016北京集训测试赛(六)Problem A: 冒泡排序的更多相关文章

  1. 2016北京集训测试赛(十六)Problem C: ball

    Solution 这是一道好题. 考虑球体的体积是怎么计算的: 我们令\(f_k(r)\)表示\(x\)维单位球的体积, 则 \[ f_k(1) = \int_{-1}^1 f_{k - 1}(\sq ...

  2. 2016北京集训测试赛(十六)Problem B: river

    Solution 这题实际上并不是构造题, 而是一道网络流. 我们考虑题目要求的一条路径应该是什么样子的: 它是一个环, 并且满足每个点有且仅有一条出边, 一条入边, 同时这两条边的权值还必须不一样. ...

  3. 2016北京集训测试赛(十六)Problem A: 任务安排

    Solution 这道题告诉我们, 不能看着数据范围来推测正解的时间复杂度. 事实证明, 只要常数足够小, \(5 \times 10^6\)也是可以跑\(O(n \log n)\)算法的!!! 这道 ...

  4. 2016北京集训测试赛(六)Problem B: 矩阵

    Solution 最小割. 参考BZOJ 3144切糕 在那道题的基础上将建图方法稍作变形: 我们对格子进行黑白染色, 对于两个格子之和\(\le k\)的限制, 就可以确定其中一个是白色格子, 一个 ...

  5. 【2016北京集训测试赛(十六)】 River (最大流)

    Description  Special Judge Hint 注意是全程不能经过两个相同的景点,并且一天的开始和结束不能用同样的交通方式. 题解 题目大意:给定两组点,每组有$n$个点,有若干条跨组 ...

  6. 2016北京集训测试赛(十七)Problem C: 数组

    Solution 线段树好题. 我们考虑用last[i]表示\(i\)这个位置的颜色的上一个出现位置. 考虑以一个位置\(R\)为右端点的区间最远能向左延伸到什么位置: \(L = \max_{i \ ...

  7. 2016北京集训测试赛(十七)Problem B: 银河战舰

    Solution 好题, 又是长链剖分2333 考虑怎么统计答案, 我场上的思路是统计以一个点作为结尾的最长上升链, 但这显然是很难处理的. 正解的方法是统计以每个点作为折弯点的最长上升链. 具体的内 ...

  8. 2016北京集训测试赛(十七)Problem A: crash的游戏

    Solution 相当于要你计算这样一个式子: \[ \sum_{x = 0}^m \left( \begin{array}{} m \\ x \end{array} \right) \left( \ ...

  9. BZOJ 4543 2016北京集训测试赛(二)Problem B: thr 既 长链剖分学习笔记

    Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...

随机推荐

  1. install golang plugin in webstrom

    https://github.com/go-lang-plugin-org/go-lang-idea-plugin/wiki/Documentation

  2. 2、HTML基础总结 part-2

    1.表单一 <html> <body> <form> 姓名: <input type="text" name="name&quo ...

  3. 图说不为人知的IT传奇故事-2-IBM咬不动的胡桃

    此系列文章为“图说不为人知的IT传奇故事”,各位大忙人可以在一分钟甚至几秒内了解把握整个内容,真可谓“大忙人的福利”呀!!希望各位IT界的朋友在钻研技术的同时,也能在文学.历史上有所把握.了解这些故事 ...

  4. Java EnumSet工作原理初窥

    EnumSet是Java枚举类型的泛型容器,Java既然有了SortedSet.TreeSet.HashSet等容器,为何还要多一个EnumSet<T>呢?答案肯定是EnumSet有一定的 ...

  5. jmeter连接数据库之增删改查

    配置jdbc: 查询sql配置: 插入sql配置: 修改sql配置: 删除sql配置:

  6. APM简介

    1.什么是APM APM (应用性能管理) - Application Performance Management & Monitoring在信息科学和系统控制领域,APM致力于监控和管理应 ...

  7. [oldboy-django][2深入django]FBV + CBV + 装饰器

    FBV django CBV & FBV - FBV function basic view a. urls 设置 urls(r'^test.html$', views.test) b. vi ...

  8. PAT A+B格式

    A + B格式(20) 时间限制 400毫秒 内存限制 65536 kB 代码长度限制 16000 B. 判断程序 标准 作者 陈,岳 计算a + b并以标准格式输出总和 - 即数字必须用逗号分隔成三 ...

  9. 【转】Twitter-Snowflake,64位自增ID算法详解

    Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统 ...

  10. BZOJ2396 神奇的矩阵 【随机化 + 矩乘】

    题目链接 BZOJ2396 题解 一种快速判断两个矩阵是否相等的方法: 对于两个\(n * n\)矩阵,两边同时乘一个\(n * 1\)的随机矩阵,如果结果相等,那么有很大概率两个矩阵相等 如果左边是 ...