题目大意:把1到n分为不互质的数对,找最多的对数
思路:先从最大的质因数开始找,因为小的比大的更容易匹配,所以贪心的从大的开始找。
首先要预处理出所以数的最大质因数。
然后根据质因数从大往小找,当质因数大于n/2的时候 就找不到 配对了。
估计是偶数 直接配对,如果是奇数 讲2*p留出来,这样留到最后,这些数必定有2的公因子。
代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <bitset>
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define re register
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(a) ((a)&-(a))
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
#define fi first
#define rep(i,n) for(int i=0;(i)<(n);i++)
#define rep1(i,n) for(int i=1;(i)<=(n);i++)
#define se secondusing namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll mod=1e9+7;
const ll N =2e5+10;
const double eps = 1e-4;
const double pi=acos(-1);
int gcd(int a,int b){return !b?a:gcd(b,a%b);}int x[4]= {-1,0,1,0}, dy[4] = {0,1,0,-1};
int st[N];vector<int> p[N];
int c[N];
int mx[N];
int r[N];
int idx=0;
int k[N];
int id;
void get_primes(int n)
{st[1]=1;for (int i = 2; i <= n; i ++ ){if (!st[i]){mx[i]=i;for(int j=i+i;j<=n;j+=i){st[j]=1;mx[j]=i;}}}
}void solve()
{idx=0;int n;cin>>n;for(int i=2;i<=n;i++){if(!st[i]&&2*i>n) continue;p[mx[i]].push_back(i);}vector<pii> a;for(int i=n;i>=2;--i){int le=p[i].size();if(le%2==1){id=0;r[idx++]=i*2;for(int j=0;j<le;j++) if(p[i][j]!=2*i) k[id++]=p[i][j];for(int j=0;j<id;j+=2) a.push_back({k[j],k[j+1]});}else{for(int j=0;j<le;j+=2) a.push_back({p[i][j],p[i][j+1]});}}for(int i=0;i+1<idx;i+=2) a.push_back({r[i],r[i+1]});cout<<a.size()<<endl;for(pii &v:a){cout<<v.fi<<" "<<v.se<<endl;}for(int i=1;i<=n;i++) p[i].clear();
}int main()
{iosint T;cin>>T;get_primes(N);//T=1;while(T--){solve();}return 0;
}