轮换 $g : (q_1, q_2, q_3, \dots, q_k)$ 是一个从 $\{1, 2, \dots, n\}$ 到 $\{1, 2, \dots, n\}$ 的一一映射,它将 $q_1$ 映射为 $q_2$,$q_2$ 映射为 $q_3$,$\dots$,$q_k$ 映射为 $q_1$,而在 $q_1, q_2, \dots, q_k$ 中没有出现的整数映射到自身。即:$g(q_1) = q_2, g(q_2) = q_3, \dots, g(q_k) = q_1$,而对于在 $q_1, q_2, \dots, q_k$ 中没有出现的 $x$,有 $g(x) = x$。
定义将轮换 $g$ 应用到一个 $\{1, 2, \dots, n\}$ 的排列 $(p_1, p_2, \dots, p_n)$ 上的结果为: $$g(p_1, p_2, \dots, p_n) = (g(p_1), g(p_2), \dots, g(p_n))$$
例如,对排列 $(3, 1, 5, 4, 2)$ 应用轮换 $(1, 3, 4)$ 进行变换后可得到排列 $(4, 3, 5, 1, 2)$。
给定 $\{1, 2, \dots, n\}$ 的一个排列 $(p_1, p_2, \dots, p_n)$ 和一些轮换,请给出一种使用尽量少的轮换次数将该排列变换为 $(1, 2, \dots, n)$ 的方法。每个轮换可以使用多次。
输入格式
这是一道提交答案的试题,在你的目录下有 10 个输入文件 sort*.in。
输入文件的第一行为两个整数 $n$ 和 $m$,分别表示序列的长度和可使用的轮换个数。
第二行有 $n$ 个整数,是给定的初始排列 $(p_1, p_2, \dots, p_n)$。
接下来 $m$ 行,每行一个轮换,每一行的第一个数为 $k$,接下来 $k$ 个数为 $q_1, q_2, \dots, q_k$,表示轮换 $(q_1, q_2, q_3, \dots, q_k)$。
输出格式
对于每一个输入文件,在目录下给出对应的输出文件 sort*.out。
输出的第一行包含一个整数 $c$,表示所需的轮换次数。
接下来 $c$ 行,每行一个 $1$ 至 $m$ 的整数,表示使用的轮换编号。
评分标准
对于每个测试点,如果你没有输出、输出不合法或不能将排列变为指定的序列,则得 0 分。
对于每个数据,我们设有三个评分参数 $m_1, m_2$ 和 $m_3$。
- 若 $c \le m_1$,得 10 分;
- 若 $m_1 < c \le m_2$,得 5 分;
- 若 $m_2 < c \le m_3$,得 3 分;
- 若 $m_3 < c \le 1\,000\,000$,得 1 分;
- 若 $c > 1\,000\,000$,得 0 分;
其中,对第 8 个点,$m_1 = 2\,300, m_2 = 2\,400, m_3 = 3\,000$; 对第 9 个点,$m_1 = 69\,000, m_2 = 75\,000, m_3 = 100\,000$; 对第 10 个点,$m_1 = m_2 = m_3 = 1\,000\,000$。
说明
在你的目录下有一个程序 checker 可以用来测试你的输出结果,你可以在终端中使用以下命令来检查你的输出结果:
./checker N
其中 $N$ 为测试点的编号,例如,要测试第 3 个测试点可以使用 ./checker 3。
该程序会检测你的输出是否合法。对于合法的输出,checker 会输出“Right.”,否则会输出错误信息。
样例
输入 1
4 2 4 3 1 2 2 4 2 3 1 3 4
输出 1
2 2 1