从给定集合中选数并构造序列 $\{a_i\}$,需要满足 $a_{\gcd (i,j)} \neq \gcd(a_i,a_j) \mid \forall 1 \le i < j \le n$ 并且构造出的序列字典序最大。

不妨从反面分析,考虑满足 $a_{\gcd (i,j)} = \gcd (a_i,a_j)$。当 $i \mid j$ 时,$\gcd (i,j) = i$,$a_i \mid a_j$。进一步的,当 $i \nmid j$ 时,是否也存在一个 $i$,满足 $a_{\gcd (i,j)} = \gcd (a_i,a_j)$ 呢?

假设存在这个 $i$,我们设 $g = \gcd (i,j)$,那么 $a_g = \gcd (a_i,a_j)$ 且 $g < i$。由于 $g \mid i$,等价于 $g = \gcd (g,i)$,由上面的结论可知 $a_{\gcd (g,i)} = \gcd (a_g,a_i)$。此时与题目的条件不符合,故假设不成立。

所以说在构造 $a_i$ 时,只需要考虑序列以 $i$ 的因数(且小于 $i$)为下标的数,预处理因数即可。在构造的时候,我们可以将所有以 $i$ 的因数为下标的数放入 $\mathrm{set}$ 中,然后从最大的数开始,查找到第一个未出现在集合中的数即可退出循环。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#define init(x) memset (x,0,sizeof (x))
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
using namespace std;
const int MAX = 1e5 + 5;
const int M = 1e5;
const int MOD = 1e9 + 7;
inline int read ();
vector <int> ans,p[MAX];
int t,n,m,a[MAX];
int main ()
{
//freopen (".in","r",stdin);
//freopen (".out","w",stdout);
for (int i = 1;i <= M;++i)
for (int j = i + i;j <= M;j += i) p[j].push_back (i);//j 的因数
t = read ();
while (t--)
{
n = read ();m = read ();
for (int i = 1;i <= m;++i) a[i] = read ();
sort (a + 1,a + 1 + m);ans.clear ();
for (int i = 1;i <= n;++i)
{
set <int> invaild;
for (auto item : p[i]) invaild.insert (ans[item - 1]);
for (int j = m;j;--j)
{
if (invaild.find (a[j]) == invaild.end ())
{
ans.push_back (a[j]);
break;
}
}
if (ans.size () != i) break;
}
if (ans.size () != n) puts ("-1");
else {for (auto item : ans) printf ("%d ",item);puts ("");}
}
return 0;
}
inline int read ()
{
int s = 0;int f = 1;
char ch = getchar ();
while ((ch < '0' || ch > '9') && ch != EOF)
{
if (ch == '-') f = -1;
ch = getchar ();
}
while (ch >= '0' && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * f;
}