Codeforces Round #565 (Div. 3) D. Recover it!

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;
}

猜你喜欢

转载自www.cnblogs.com/c4Lnn/p/12396907.html
今日推荐