2020牛客暑期多校训练营(第四场)H-Harder Gcd Problem

在这里插入图片描述

Statement

  • 1   N 1~N 的数选尽量多的组,使得每组 g c d gcd 大于 1 1 。输出一组特解。

题解

  • 2 p > n 2p>n p p 必然不能匹配,将它们除去。倒序枚举所有质因子 p p ,考虑所有是 p p 的倍数、且未被匹配的数,任意将它们进行匹配。如果个数是奇数就留下 2 p 2p 。最后把剩下的偶数都随意匹配一下。

Code

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=2e5+10;
using namespace std;
bool np[N],vis[N];
int T,n,tot,m,p[N],val[N];
pair<int,int> ans[N];
void sieve(){
    np[0]=np[1]=1;
    for(int i=2;i<N;i++){
        if(!np[i]) p[++tot]=i;
        for(int j=1;j<=tot&&i*p[j]<N;j++){
            np[i*p[j]]=1;
            if(i%p[j]==0) break;
        }
    }
}int main(){
    sieve();
    scanf("%d",&T);
    while(T--){
        memset(vis,0,sizeof(vis));
        scanf("%d",&n),m=0;
        for(int i=n;i>=2;i--){
            if(np[i]) continue;
            int cnt=0;
            for(int j=1;i*j<=n;j++)if(!vis[i*j]) val[++cnt]=i*j;
            if(cnt<=1) continue;
            if(cnt&1){
                ans[++m]=make_pair(val[1],val[3]);
                vis[val[1]]=vis[val[3]]=1;
                for(int i=4;i<=cnt;i+=2) ans[++m]=make_pair(val[i],val[i+1]),vis[val[i]]=vis[val[i+1]]=1;
            }else for(int i=1;i<=cnt;i+=2) ans[++m]=make_pair(val[i],val[i+1]),vis[val[i]]=vis[val[i+1]]=1;
        }printf("%d\n",m);
        for(int i=1;i<=m;i++) printf("%d %d\n",ans[i].first,ans[i].second);
    }
}

猜你喜欢

转载自blog.csdn.net/ding_ning123/article/details/107498266