• 2020牛客暑期多校第四场-H Harder Gcd Problem(贪心构造)


    题目大意:给你一个序列1-n,你要找到尽可能多的匹配使得每个匹配值的gcd>1,输出匹配的个数和每个匹配

    输入

    2
    4
    10

    输出

    1
    2 4
    4
    3 9
    5 10
    8 2
    4 6

    emmm,这题的话应该还是感觉比较好写的,先将素数筛出了,对每个素数p的点放入p,2p,3p,4p...kp(kp<=n),那么里面的数就可以任意匹配了,那么对于2这个素数我们先不急,我们先将3到n/2以内的素数的内容放好,对于每个素数的size,如果里面是偶数的话我们就任意匹配,如果是奇数的话,我们将2p保留下来,放入到2的内容中,剩余的任意匹配,最后我们再出来2这个值就好了。

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    #define debug printf("@#$#@%")
    const int mac=2e5+10;
    
    int vis[mac];
    vector<int>prim[mac];
    int vs[mac],val[mac];
    
    int main(int argc, char const *argv[])
    {
        int t,n;
        scanf ("%d",&t);
        for (int i=2; i<=sqrt(mac); i++)
            if (!vis[i]) 
                for (int j=i*i; j<mac; j+=i)
                    vis[j]=1;
        int cnt=0;
        for (int i=2; i<mac; i++)
            if (!vis[i]) val[++cnt]=i;
        while (t--){
            int n;
            scanf ("%d",&n);
            for (int i=1; i<=n; i++) vs[i]=0;
            for (int i=1; 2*val[i]<=n; i++) prim[i].clear(),prim[i].push_back(val[i]);
            prim[1].push_back(4);
            vector<pair<int,int>>ans;
            for (int i=2; 2*val[i]<=n; i++){
                for (int j=2*val[i]; j<=n; j+=val[i]){
                    if (vs[j]) continue;            
                    prim[i].push_back(j);
                    vs[j]=1;
                }
                if ((prim[i].size()&1) && prim[i].size()>1){
                    ans.push_back(make_pair(prim[i][0],prim[i][2]));
                    for (int j=3; j<prim[i].size(); j+=2){
                        ans.push_back(make_pair(prim[i][j],prim[i][j+1]));
                    }
                    prim[1].push_back(prim[i][1]);
                }
                else {
                    for (int j=0; j<prim[i].size(); j+=2)
                        ans.push_back(make_pair(prim[i][j],prim[i][j+1]));
                }
                prim[i].clear();
            }
            for (int j=2*3; j<=n; j+=2){
                if (vs[j]) continue;
                prim[1].push_back(j);
            }
            if ((prim[1].size()&1)) 
                for (int i=1; i<prim[1].size(); i+=2)
                    ans.push_back(make_pair(prim[1][i],prim[1][i+1]));
            else 
                for (int i=0; i<prim[1].size(); i+=2)
                    ans.push_back(make_pair(prim[1][i],prim[1][i+1]));
            printf ("%d
    ",ans.size());
            for (int i=0; i<ans.size(); i++)
                printf("%d %d
    ",ans[i].first,ans[i].second);
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    Linux file命令详解
    Linux stat命令详解
    Linux cut命令详解
    Linux tr命令详解
    Linux grep/egrep命令详解
    Linux awk命令详解
    Linux xargs命令详解
    MVC设计模式
    qt博客
    android
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13348265.html
Copyright © 2020-2023  润新知