Statement
- 把
1 N的数选尽量多的组,使得每组
gcd大于
1。输出一组特解。
题解
-
2p>n的
p必然不能匹配,将它们除去。倒序枚举所有质因子
p,考虑所有是
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);
}
}