两数列 \(a , b\),如果 \(a_i\) 是素数,那么 \(b\) 数列里添加上第 \(a_i\) 个素数(\(2\) 为第一个),如果不是素数,那么 \(b\) 数列里添加上 \(a_i\) 的最大因子。现在给出添加完之后的 \(b\) 数列,求出 \(a\) 数列。
Solution
从大到小枚举合数,删去它的最大因子
从小到大枚举质数 \(p\),删去第 \(p\) 个质数
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 3000005;
int prime[MAXN+1],isp[MAXN];
void presolve() {
memset(prime,0,sizeof prime);
for(int i=2;i<=MAXN;i++) {
if(!prime[i]) prime[++prime[0]]=i;
for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++) {
prime[prime[j]*i]=1;
if(i%prime[j]==0) break;
}
}
for(int i=1;i<=prime[0];i++) isp[prime[i]]=1;
}
int n,a[MAXN],s[MAXN],o[MAXN],ind;
signed main() {
//ios::sync_with_stdio(false);
presolve();
cin>>n;
for(int i=1;i<=2*n;i++) cin>>a[i];
sort(a+1,a+2*n+1);
for(int i=1;i<=2*n;i++) s[a[i]]++;
for(int i=2*n;i>=1;--i) if(a[i]&&s[a[i]]) {
if(!isp[a[i]]) {
int t=1;
while(a[i]%prime[t] && t<2e5) ++t;
t=prime[t];
s[a[i]/t]--;
s[a[i]]--;
o[++ind]=a[i];
a[i]=0;
}
}
for(int i=1;i<=2*n;i++) if(a[i]&&s[a[i]]) {
if(isp[a[i]]) {
int t=prime[a[i]];
s[t]--;
s[a[i]]--;
o[++ind]=a[i];
a[i]=0;
}
}
for(int i=1;i<=n;i++) cout<<o[i]<<" ";
}