2020牛客暑期多校训练营Harder Gcd Problem(数学)

Harder Gcd Problem

题目描述

在这里插入图片描述

输入描述:

在这里插入图片描述

输出描述:

在这里插入图片描述

示例1

输入

2
4
10

输出

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

题目大意

给定一个n,求1~n中有多少对匹配。
匹配的条件是不互质。
CF上有原题……(尽管我没有做过

分析

亿个想法

第一秒就想到1肯定是排除,因为在互质的概念里,1简直就是个bug。(de不掉的bug

首先肯定是直觉想到质数。然后想到质数的平方肯定是和质数匹配是最优的。然后傻掉了,一堆人在那边研究一个100%TLE的代码,最后还是WA了,然后手动算了100的结果,最后发现是SPJ,真是去世……

研究过程中,发现可以把偶数先扔掉,因为偶数和偶数是必然能匹配的。

结合一下

偶数可以看做是2的倍数,也就是素数的倍数。而素数的平方也就是素数的素数倍。由此,大胆地猜想,素数和素数的倍数匹配是最优的。

手动算算

在这里插入图片描述
可以发现,7和11是没有匹配的,所以当该素数的倍数在≤n的情况下,只有它本身的话是不匹配的。
然后考虑从5开始还是从2开始。

显然,如果2的匹配有剩余,那么在后续中更大的素数匹配时是很难把2的倍数匹配掉。而相反的,如果5的匹配有剩余,2和3可以轻易地将剩余的匹配掉,不重不漏。

但是也有可能出现素数倍数个数是奇数的情况,此时就出现了不能匹配完,此时要把2倍的剩下来,因为它可以和偶数匹配,所有的素数中,2的倍数是最多的,因此可以最大限度地解决剩余的问题。

综述策略

把小于等于n的素数筛出来,然后从大到小去求所有素数的倍数,然后两两匹配,若是奇数个,则将2倍的剩余。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=2e5+10;
struct node{
    int ans1,ans2;
    node(){}
    node(int a1,int a2){
        ans1=a1,ans2=a2;
    }
};
int a[MAXN];
bool pr[MAXN],vis[MAXN];//pr 筛素数  vis 是否已匹配
vector<node> ans;//存储匹配
int main()
{
    for(int i=2;i<MAXN;i++)
        if(!pr[i]) for(int j=i*2;j<MAXN;j+=i) pr[j]=1;//筛素数
    int t,n,num;
    for(scanf("%d",&t);t--;){
        scanf("%d",&n);memset(vis,0,sizeof(vis));ans.clear();
        for(int i=n;i>=2;i--){
            if(pr[i]) continue;num=0;//如果当前这个不是素数,跳过
            for(int j=i;j<=n;j+=i) if(!vis[j]) a[++num]=j;//把倍数存到一个数组里,也可以用vector
            if(num<=1) continue;//如果只有本身一个,则无法匹配
            if(num&1){
                ans.push_back(node(a[1],a[3]));//把2倍扔掉,本身和3倍匹配
                vis[a[1]]=vis[a[3]]=1;
                for(int j=4;j<=num;j+=2) ans.push_back(node(a[j],a[j+1])),
                                        vis[a[j]]=vis[a[j+1]]=1;
            }
            else for(int j=1;j<=num;j+=2) ans.push_back(node(a[j],a[j+1])),
                                        vis[a[j]]=vis[a[j+1]]=1;//两两匹配
        }
        printf("%d\n",ans.size());
        for(int i=0;i<ans.size();i++) printf("%d %d\n",ans[i].ans1,ans[i].ans2);
    }
}

END

感谢。

猜你喜欢

转载自blog.csdn.net/zhangchizc/article/details/107490830