#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define mp make_pair
int n;
int b[400040];
int l[3000030];
int c[200020];
set<int> s;
int t;
void init(int x)
{
l[0] = l[1] = 114;
for (int i = 2; i <= x; i++)
{
if (l[i] == 0)
{
for (int j = 2 * i; j <= x; j += i)
{
if (!l[j])
l[j] = i;
}
s.insert(i);
c[++t] = i;
}
}
}
multiset<int> s1, s2;
vector<int> z;
main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n * 2; i++)
{
cin >> b[i];
}
init(2750131);
for (int i = 1; i <= 2 * n; i++)
{
if (s.find(b[i]) != s.end())
s1.insert(b[i]);
else
s2.insert(-b[i]);
}
int cc = 0;
for (auto &i : s2)
{
if (s2.size() == 0)
break;
if (s2.find(i) == s2.end())
continue;
if (s2.find(i / l[-i]) != s2.end())
{
z.pb(-i);
s2.erase(s2.find(i));
s2.erase(s2.find(i / l[-i]));
}
else
{
z.pb(-i);
s2.erase(s2.find(i));
s1.erase(s1.find((-i) / l[-i]));
}
}
// int c = 0;
if (s1.size() != 0)
for (auto &i : s1)
{
if (s1.find(i) == s1.end())
continue;
cout << i << " ";
s1.erase(s1.find(i));
s1.erase(s1.find(c[i]));
}
for (auto &i : z)
cout << i << " ";
return 0;
}
死因 “RE on 30”
大致思路:考虑到约数只有可能是原本序列中的或者其他一个约数除出来的,所以从大到小判约数,如果除出来时素数那就删素数。最后判断素数。
ci 表示第 i 个素数。
li 表示 i 这个数的最小约数
s1 是素数集,s2 是约数集。