zoukankan      html  css  js  c++  java
  • 2020牛客多校第四场H

    题意:

    在{1,2,3,...,n}中找到两个没有交集的序列使得gcd(ai, bi)>1,即找到ai和bi两两配对,使得他们不互质

    思路:

    显而易见,> n/2的素数是不能配对的。我们可以先把1~n的素数筛出来,从大到小枚举每个素数p(从小到大会漏)。

    对于每个素数p,2p,3p,...... ,kp (k == n / p)两两配对,如果k为奇数,则把2p留下。

    最后把留下的偶数两两配对,得到最终答案。

    Code:

    #pragma GCC optimize(3)
    #pragma GCC optimize(2)
    #include <map>
    #include <set>
    #include <array>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <stdlib.h>
    #include <algorithm>
    #include <unordered_map>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> PII;
    
    #define Time (double)clock() / CLOCKS_PER_SEC
    
    #define sd(a) scanf("%d", &a)
    #define sdd(a, b) scanf("%d%d", &a, &b)
    #define slld(a) scanf("%lld", &a)
    #define slldd(a, b) scanf("%lld%lld", &a, &b)
    
    const int N = 2e5 + 10;
    const ll M = 4e12;
    const int mod = 1e9 + 7;
    
    int t;
    int n, cnt;
    int primes[N];
    bool st[N], vis[N];
    vector<pair<int, int>> v;
    
    
    void get(int n)
    {
        cnt = 0;
        for (int i = 2; i <= n; i++)
        {
            if (!st[i])
                primes[cnt++] = i;
            for (int j = 0; primes[j] <= n / i; j++)
            {
                st[primes[j] * i] = true;
                if (i % primes[j] == 0)
                    break;
            }
        }
    }
    
    int main()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("/home/jungu/code/in.txt", "r", stdin);
        // freopen("/home/jungu/code/out.txt", "w", stdout);
    #endif
        // ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
    
        sd(t);
        get(N - 10);
        while (t--)
        {
            sd(n);
    
            for (int i = 1; i <= n; i++)
            {
                vis[i] = false;
            }
            v.clear();
    
            int num = -1, a, b;
            for (int i = n / 2; i >= 2; i--)
            {
                if(st[i]) continue;
    
                if(i > n / 2) continue;
                int k = n / i * i;  
    
                for( ; k >= 0; k -= i){
                    while(vis[k] && k >= 0){
                        k -= i;
                    }
                    if(k == 0){
                        break;
                    }
                    vis[k] = true;
                    a = k;
                    while(vis[k] && k >= 0){
                        k -= i;
                    }
                    if(k == 0){
                        break;
                    }
                    vis[k] = true;
                    if(k == 2 * i){
                        if(num == -1){
                            num = k;
                        }
                        else{
                            v.push_back({k, num});
                            num = -1;
                        }
                        k -= i;
                        vis[k] = true;
                    }
                    v.push_back({a, k});
    
                }
                
            }
            printf("%d
    ", (int)v.size());
            for(auto x : v){
                printf("%d %d
    ", x.first, x.second);
            }
        }
    
        return 0;
    }
  • 相关阅读:
    工具函数(代码块的大小,代码块起始地址,提升进程权限)
    在共享DLL中使用MFC 和在静态库中使用MFC的区别
    虚拟机检测绕过总结--不定时更新
    OSGI原形(.NET)
    iOS开发技术分享(1)— iOS本地数据存储
    将JSON映射为实体对象(iOS篇)
    灵活的路由(上)
    github开源项目
    EF里查看/修改实体的当前值、原始值和数据库值以及重写SaveChanges方法记录实体状态
    实体能否处于非法状态
  • 原文地址:https://www.cnblogs.com/jungu/p/13347999.html
Copyright © 2011-2022 走看看