题面:
有两种线性筛法,都可以做这个题
第一种线筛维护的是最大质因子,是最切合本题的解法:
#include<bits/stdc++.h>
#include<bits/extc++.h>
#define oo INT_MAX
#define ll long long
#define db double
#define mp(a, b) make_pair(a, b)
#define met(a, b) memset(a, b, sizeof(a))
#define maxn 3000009
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i = (a); i < (b) ;++i)
using namespace std;
using namespace __gnu_pbds;
int prime[maxn], v[maxn];//prime[i]代表质数i是第几个,不是质数则为0, v[i]代表i的最大质因子
void sieve(){//1~maxn内的质数
_rep(i, 1, maxn)v[i] = i;
_for(i, 2, maxn){
if(v[i] != i){//i是合数
v[i] = i / v[i];//换成最大质因子
continue;
}
for(ll j = i * 1ll * i; j < maxn ; j += i){
v[j] = min(v[j], i);
}
}
int cur = 0;
_for(i, 2, maxn){
if(v[i] == i) prime[i] = ++cur;
}
}
int cnt[maxn];
int main(){
ios::sync_with_stdio(0);
int n;
cin >> n;
_rep(i, 1, 2 * n){
int x;cin >> x;
++cnt[x];
}
sieve();
vector<int> res;
_rev(i, maxn - 1, 0){
while (cnt[i] > 0)
{
if(v[i] == i){//质数
--cnt[prime[i]];
res.push_back(prime[i]);
}else {
--cnt[v[i]];
res.push_back(i);
}
cnt[i]--;
}
}
for(auto it : res){
printf("%d ", it);
}
//system("pause");
}