zoukankan      html  css  js  c++  java
  • 【2020牛客多校第四场 H题】Harder Gcd Problem

    Harder Gcd Problem

    题意

    给出 n 个数字1 2 3 .... n ,让构造出两个集合 A,B ,满足以下条件:

    1. A ∩ B == ∅ and | A | == | B | == m
    2. (gcd(A_i,B_i) > 1)

    思路

    按照每个数字的最小质因子分组。

    2:

    3:

    5:

    7:

    ...

    初始一直想的是从 2组开始,组中每两个作为一对输出,如果有奇数个数字,那么将最后一个数字除完所有的 2 ,将其放到次小质因子组中去。就这样一直遍历。然后直接找出了反例。。。

    然后就想着改进,但是想出的方法都给人一种不完美的感觉。

    题解

    从 3 开始进行,如果当前组的数字个数为奇数,那么从 2 组中判断是否有最小数字的 2 倍,如果有那么这俩数字作为一对,其他相邻的作为一对。

    就是把 2组中的数字当做备选,最后 2 组再自行匹配。

    代码

    #include <bits/stdc++.h>
    #define emplace_back push_back
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int N = 1e6 + 10;
    
    int vis[N],pri[N],tot;
    void solve(int n)
    {
        for(int i=2; i<=n; i++)
        {
            if(!vis[i])
                pri[++tot]=i;
            for(int j=1; j<=tot; j++)
            {
                if(i*pri[j]>n)
                    break;
                vis[i*pri[j]]=pri[j];//纪录最小的素因子
                if(i%pri[j]==0)
                    break;
            }
        }
    }
    
    vector<int>vec[N];
    vector<pair<int,int> >ans;
    int sign[N];
    int main()
    {
        solve(200005);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n;
            scanf("%d",&n);
            for(int i=1; i<=n; i++)
                vec[i].clear();
            ans.clear();
            for(int i=2; i<=n; i++)
            {
                if(vis[i]==0) vis[i]=i;
                sign[i]=0;
                vec[vis[i]].pb(i);
            }
            for(int i=3;i<=n;i++)
            {
                if(vec[i].size()%2){
                    for(int j=1;j+1<vec[i].size();j+=2)
                        ans.pb(make_pair(vec[i][j],vec[i][j+1]));
                    if(sign[vec[i][0]*2]==0&&2*vec[i][0]<=n){
                        ans.pb(make_pair(vec[i][0],vec[i][0]*2));
                        sign[vec[i][0]*2]=1;
                    }
                }
                else{
                    for(int j=0;j+1<vec[i].size();j+=2){
                        ans.pb(make_pair(vec[i][j],vec[i][j+1]));
                    }
                }
            }
            int pre=0;
            for(int v:vec[2]){
                if(sign[v]==0){
                    if(pre==0) pre=v;
                    else
                    {
                        ans.pb(make_pair(pre,v));
                        pre=0;
                    }
                }
            }
            printf("%d
    ",ans.size());
            for(auto now:ans){
                printf("%d %d
    ",now.first,now.second);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    ES学习(十)
    ES学习(九)
    ES学习(八)
    ES学习(七)--documentAPI
    ES学习(六)--shard和replica机制
    ES学习(四)--嵌套聚合、下钻分析、聚合分析
    uniapp中常见的请求方法封装 --来之插件市场(全局方法封装(请求/正则/URI)
    工具/插件
    express中文件的上传 multer
    express中开发常用
  • 原文地址:https://www.cnblogs.com/valk3/p/13357070.html
Copyright © 2011-2022 走看看