Codeforces Round #565 (Div. 3)--D. Recover it!--思维+欧拉筛

D. Recover it!

Authors guessed an array aa consisting of nn integers; each integer is
not less than 22 and not greater than 2⋅1052⋅105. You don’t know the
array aa, but you know the array bb which is formed from it with the
following sequence of operations:

Firstly, let the array bb be equal to the array aa; Secondly, for each
ii from 11 to nn: if aiai is a prime number, then one integer paipai
is appended to array bb, where pp is an infinite sequence of prime
numbers (2,3,5,…2,3,5,…); otherwise (if aiai is not a prime number),
the greatest divisor of aiai which is not equal to aiai is appended to
bb; Then the obtained array of length 2n2n is shuffled and given to
you in the input. Here paipai means the aiai-th prime number. The
first prime p1=2p1=2, the second one is p2=3p2=3, and so on.

Your task is to recover any suitable array aa that forms the given
array bb. It is guaranteed that the answer exists (so the array bb is
obtained from some suitable array aa). If there are multiple answers,
you can print any.

Input

The first line of the input contains one integer nn
(1≤n≤2⋅1051≤n≤2⋅105) — the number of elements in aa.

The second line of the input contains 2n2n integers
b1,b2,…,b2nb1,b2,…,b2n (2≤bi≤27501312≤bi≤2750131), where bibi is the
ii-th element of bb. 27501312750131 is the 199999199999-th prime
number.

Output

In the only line of the output print nn integers a1,a2,…,ana1,a2,…,an
(2≤ai≤2⋅1052≤ai≤2⋅105) in any order — the array aa from which the
array bb can be obtained using the sequence of moves given in the
problem statement. If there are multiple answers, you can print any.

Examples

input

Copy

3
3 5 2 3 2 4
output

Copy

3 4 2 
input

Copy

1
2750131 199999
output

Copy

199999 
input

Copy

1
3 6
output

Copy

6 

题解如下

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int Len = 1e6;
int prime[Len * 3];
int ar[Len * 3];
int br[3 * Len];
int barrel[3 * Len];
vector<int> vec;
int n;

bool cmp(int a,int b)
{
    return a > b;
}
void Prime()
{
    for(int i = 2; i <= Len * 3; i ++)
        prime[i] = 1;
    //素数筛选法
    for(int i = 2; i * i <= Len * 3; i ++)
    {
        if(prime[i])
        {
            for(int j = i * i; j <= Len * 3; j += i)
                prime[j] = 0;
        }
    }
}

void init()
{
    Prime();

    int pos = 1;
    for(int i = 2; i <= Len * 3; i ++)
    {
        if(prime[i])
        {
            ar[pos ++] = i;
        }
    }
    //输入
    for(int i = 1; i <= 2 * n; i ++)
    {
        scanf("%d",&br[i]);
    }
    //统计各个数字出现的次数
    for(int i = 1; i <= 2 * n; i ++)
    {
        barrel[br[i]] ++;
    }
    sort(br + 1 , br + 2 * n + 1 , cmp);
}
void Solve()
{
    init();

    for(int i = 1; i <= 2 * n; i ++)
    {
        int cnt = barrel[br[i]];
        if(cnt > 0)
        {
            if(! prime[br[i]])
            {
                int mx_divisor;
                for(int j = 2; ; j ++)
                    if(br[i] % j == 0)
                    {
                        mx_divisor = br[i] / j;
                        break;
                    }

                if(barrel[mx_divisor] > 0)
                {
                    barrel[mx_divisor] --;
                    vec.push_back(br[i]);
                    barrel[br[i]] --;
                }
            }
            else
            {
                int pri = ar[br[i]];
                if(barrel[pri] > 0)
                {
                    barrel[pri] --;
                    vec.push_back(br[i]);
                    barrel[br[i]] --;
                }
            }
        }
    }

    for(auto x : vec)
        printf("%d ",x);
}

int main()
{
    //freopen("test.txt","r",stdin);
    scanf("%d",&n);
    Solve();

    return 0;
}
发布了102 篇原创文章 · 获赞 150 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34261446/article/details/104105843