题目描述
输入描述:
输出描述:
示例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){<