悬 2 关求调
  • 板块CF1176D Recover it!
  • 楼主zajasi
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/11/28 21:50
  • 上次更新2024/11/29 08:47:18
查看原帖
悬 2 关求调
754000
zajasi楼主2024/11/28 21:50
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define mp make_pair
int n;
int b[400040];
int l[3000030];
int c[200020];
set<int> s;
int t;
void init(int x)
{
    l[0] = l[1] = 114;
    for (int i = 2; i <= x; i++)
    {
        if (l[i] == 0)
        {
            for (int j = 2 * i; j <= x; j += i)
            {
                if (!l[j])
                    l[j] = i;
            }
            s.insert(i);
            c[++t] = i;
        }
    }
}
multiset<int> s1, s2;
vector<int> z;
main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (int i = 1; i <= n * 2; i++)
    {
        cin >> b[i];
    }
    init(2750131);
    for (int i = 1; i <= 2 * n; i++)
    {
        if (s.find(b[i]) != s.end())
            s1.insert(b[i]);
        else
            s2.insert(-b[i]);
    }
    int cc = 0;
    for (auto &i : s2)
    {
        if (s2.size() == 0)
            break;
        if (s2.find(i) == s2.end())
            continue;
        if (s2.find(i / l[-i]) != s2.end())
        {
            z.pb(-i);
            s2.erase(s2.find(i));
            s2.erase(s2.find(i / l[-i]));
        }
        else
        {
            z.pb(-i);
            s2.erase(s2.find(i));
            s1.erase(s1.find((-i) / l[-i]));
        }
    }
    // int c = 0;
    if (s1.size() != 0)
        for (auto &i : s1)
        {
            if (s1.find(i) == s1.end())
                continue;    
            cout << i << " ";
            s1.erase(s1.find(i));
            s1.erase(s1.find(c[i]));
        }
    for (auto &i : z)
        cout << i << " ";
    return 0;
}

死因 “RE on 30”

大致思路:考虑到约数只有可能是原本序列中的或者其他一个约数除出来的,所以从大到小判约数,如果除出来时素数那就删素数。最后判断素数。

cic_i 表示第 ii 个素数。

lil_i 表示 ii 这个数的最小约数

s1s1 是素数集,s2s2 是约数集。

2024/11/28 21:50
加载中...