• 2020牛客多校第四场H-Harder Gcd Problem


    https://ac.nowcoder.com/acm/contest/5669/H

    题意

    从1~N的数选择尽量多的数对,使得每个数对gcd大于1,输出任意一种方案

    题解

    p*2>n 的 p 必然不能匹配,将它们除去。

    倒序枚举所有质因子 p,考虑所有是 p 的倍数、且未被匹配的数,任意将它们进行匹配。

    如果个数是奇数就留下 p*2。

    最后把剩下的偶数都随意匹配一下。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    struct READ {
        inline char read() {
        #ifdef _WIN32
            return getchar();
        #endif
            static const int IN_LEN = 1 << 18 | 1;
            static char buf[IN_LEN], *s, *t;
            return (s == t) && (t = (s = buf) + fread(buf, 1, IN_LEN, stdin)), s == t ? -1 : *s++;
        }
        template <typename _Tp> inline READ & operator >> (_Tp&x) {
            static char c11, boo;
            for(c11 = read(),boo = 0; !isdigit(c11); c11 = read()) {
                if(c11 == -1) return *this;
                boo |= c11 == '-';
            }
            for(x = 0; isdigit(c11); c11 = read()) x = x * 10 + (c11 ^ '0');
            boo && (x = -x);
            return *this;
        }
    } in;
    
    const int N = 2e5 + 50;
    int vis[N];
    int prime[N];
    int notprime[N];
    int main() {
        int tot = 0;
        int nn = 2e5 + 20;
        for (int i = 2; i <= nn; i++) {
            if (!notprime[i]) prime[++tot] = i;
            for (int j = 1; j <= tot && i * prime[j] <= nn; j++) {
                notprime[i * prime[j]] = 1;
                if (i % prime[j] == 0) break;
            }
        }
        int t; in >> t;
        while (t--) {
            int n; in >> n;
            memset(vis, 0, sizeof(vis));
            vector<int> a, b;
            for (int i = n; i >= 2; i--) {
                if (vis[i]) continue;
                if (notprime[i]) continue;
                vector<int> s;
                s.clear();
                for (int j = 1; j * i <= n; j++) {
                    if (!vis[j * i]) s.push_back(j * i);
                }
                if (s.size() == 1) continue;
                if (s.size() & 1) {
                    int cnt = 0;
                    for (int i = 0; i < s.size(); i++) {
                        if (i == 1) continue;
                        cnt++;
                        if (cnt & 1) a.push_back(s[i]);
                        else b.push_back(s[i]);
                        vis[s[i]] = 1;
                    }
                }
                else {
                    for (int i = 0; i < s.size(); i++) {
                        if (i & 1) a.push_back(s[i]);
                        else b.push_back(s[i]);
                        vis[s[i]] = 1;
                    }
                }
            }
            printf("%d
    ", a.size());
            for (int i = 0; i < a.size(); i++) {
                printf("%d %d
    ", a[i], b[i]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    codeforces 862B
    codeforces 863B
    codeforces 864B
    codeforces 867B
    codeforces 868B Race Against Time
    codeforces 869B The Eternal Immortality
    CodeForces
    nyoj 括号配对问题(模拟栈的过程)
    HDU
    nyoj 119 士兵杀敌(三)线段树
  • 原文地址:https://www.cnblogs.com/artoriax/p/13594608.html
Copyright © 2020-2023  润新知