Link
题意:
一开始序列 \(a\),\(b\) 相等,然后遍历序列 \(a\):
如果 \(a_i\) 是质数,将 \(p_{a_i}\) ( \(p\) 是质数的无限序列)加入序列 \(b\);
如果 \(a_i\) 不是质数,将 \(a_i\) 的最大因数(不等于其本身)加入序列 \(b\)。
已知序列 \(b\),求序列 \(a\)。
思路:
贪心 + 线性筛
从大到小遍历,
因为没有比 \(b_i\) 大的数,
所以 \(b_i\) 是质数,只能是质数 \(a_j\);不是质数,只能是最大因数。
代码:
#include<bits/stdc++.h>
using namespace std;
#define DEBUG cout<<"DEBUG"<<endl
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>pii;
typedef pair<ll,ll>pll;
typedef vector<int> vi;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<ll> vll;
typedef vector<pii> vpii;
const int N=3e6+5;
int prime[N];
bool vis[N];
int s[N];
int b[N];
int d[N];
int mp[N];
vi res;
int cnt;
void primes()
{
for(int i=2;i<N;i++)
{
if(!vis[i])
{
prime[++cnt]=i;
mp[i]=cnt;
vis[i]=true;
}
for(int j=1;j<=cnt;j++)
{
if(prime[j]>N/i) break;
vis[prime[j]*i]=true;
d[prime[j]*i]=i;
if(i%prime[j]==0) break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
//freopen("in.txt","r",stdin);
primes();
int n;cin>>n;
n*=2;
for(int i=1;i<=n;i++) cin>>b[i],s[b[i]]++;
sort(b+1,b+1+n);
for(int i=n;i>=1;i--)
{
if(!s[b[i]]) continue;
if(mp[b[i]]) res.push_back(mp[b[i]]),s[mp[b[i]]]--,s[b[i]]--;
else res.push_back(b[i]),s[d[b[i]]]--,s[b[i]]--;
}
for(auto x:res) cout<<x<<" ";
return 0;
}