• CodeForces 1333F


    CodeForces 1333F

    题意:是在 (S) 中挑选长度是 (2sim n) 的子集合,要求这些子集合中 (S_k{a,b,c,...}) 任意元素 (max(gcd(a,b))) 的值最小。

    首先集合是你去选的,那么先去想怎么是的最后选出的子集和中任意两个元素的 (gcd) 的最大值最小,首先考虑质数,我们先考虑把质数放到挑选出的集合中,因为当集合中只有质数时,任意两个质数的 (gcd) 都是 (1) ,最终这个最大值就是 (1) ,那么最多能够放的质数的个数就是小于等于 (n) 的质数个数 (tot), 所以前 (tot) 个都是 (1) .

    那么考虑后面的答案:例子:

    (S={1,2,3,4,5,6,7,8,9})

    现在已经选了 (2,3,5,7)(1) 没有影响先不考虑。

    那么还剩下 (4,6,8,9) 最终都要放到选择的集合中,因为 (S) 要挑选 长度是 (k(kleq n)) 的子集。

    考虑现在放什么:当前已选择的集合是 (2,3,5,7) (ans = 1)

    为了使得加入后的值最小,应该先选择 (2) 的倍数即 (4) 这样当 (4) 加入集合中时集合变为:

    (2,3,4,5,7) (ans= 2) 不能找到更小的值了。

    现在还有 (6,8,9) 考虑加入哪一个:如果加入 (8) 的话,(gcd(4,8)=4)

    加入 (6)(gcd(3,6) = 3)

    加入 (9) : (gcd(3,9) = 3)

    不可能加入 (8) 那么加入是 (6) 还是 (9) ?

    考虑后面的计算其实都是一样的。即先放 (6,9),再放 (8)

    那么最终每次的答案是当前合数的最大的因子。

    如:(9) 的最大因子是 (3)

    (8) 的最大因子是 (4)

    (6) 的最大因子是 (3)

    最后答案要排个序,这里就是象征着我每次在未选集合中挑选一个数加入已选集合。

    先尽量挑选答案小的,最后没有办法了,再加入答案大的。

    #include <bits/stdc++.h>
    #define SZ(X) ((int)(X).size())
    #define ALL(X) (X).begin(), (X).end()
    #define rep(I, N) for (int I = 1; I <= (N); ++I)
    #define repp(I, N) for (int I = 0; I < (N); ++I)
    #define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
    #define FORR(I, A, B) for (int I = (A); I >= (B); I--)
    #define SORT_UNIQUE(c) (sort(c.begin(), c.end()), c.resize(distance(c.begin(), unique(c.begin(), c.end()))))
    #define GET_POS(c, x) (lower_bound(c.begin(), c.end(), x) - c.begin())
    #define MP make_pair
    #define PB push_back
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MS1(X) memset((X), -1, sizeof((X)))
    #define LEN(X) strlen(X)
    #define F first
    #define S second
    using namespace std;
    const int N = 5e5 + 5;
    const double eps = 1e-7;
    const int mod = 1e9 + 7;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double LD;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef vector<LL> VL;
    typedef vector<PII> VPII;
    typedef pair<LL, LL> PLL;
    typedef vector<PLL> VPLL;
    LL gcd(LL a, LL b) { return b > 0 ? gcd(b, a % b) : a; }
    LL ksm(LL a, LL b)
    {
        LL ans = 1;
        while (b)
        {
            if (b & 1)
                ans = ans * a % mod;
            a = a * a % mod;
            b >>= 1;
        }
        return ans % mod;
    }
    int prime[N], is_prime[N];
    int tot = 0;
    vector<int> v;
    unordered_map<int, int> mp;
    void sieve(int n)
    {
        for (int i = 0; i <= n; i++)
            is_prime[i] = 1;
        is_prime[0] = is_prime[1] = 0;
        for (int i = 2; i <= n; i++)
        {
            if (is_prime[i])
            {
                prime[++tot] = i;
                for (int j = i + i; j <= n; j += i)
                {
                    is_prime[j] = 0;
                }
            }
        }
    }
    
    
    int main()
    {
        int n;
        cin >> n;
        sieve(n);
        for (int i = 1; i <= tot; i++)
        {
            cout << 1 << ' ';
        }
        for (int i = 2; i <= n; i++)
        {
            for (int j = i + i; j <= n; j += i)
                mp[j] = max(mp[j], i);
        }
        for (int i = 2; i <= n; i++)
        {
            if (!is_prime[i]) // 找到合数
            {
                v.push_back(mp[i]);
            }
        }
        sort(v.begin(), v.end());
        for (int i = 0; i < v.size(); i++)
            cout << v[i] << ' ';
        cout << endl;
        return 0;
    }
    
    
  • 相关阅读:
    使用window.showModalDialog的一个问题
    ASP.NET 的<system.codedom>标签
    SqlServer事务中的可重复读和序列化隔离界别
    C#使用163的SMTP服务器发送邮件
    在HTML中小心使用空格和回车
    ASP.NET 4.0的ClientIDMode属性
    C/C++中判断某一文件或目录是否存在<转>
    新公司工作有感
    网络编程(转)<下>
    VC控件ListControl的使用
  • 原文地址:https://www.cnblogs.com/strategist-614/p/12664863.html
Copyright © 2020-2023  润新知