题意
给出1-n的数字,让选择m对数字,让gcd(a_i,b_i)>1,让m尽可能大,并且输出这m对对应的数字。

思路
整体的思路就是筛法+贪心。
不过我代码写的比较复杂,比较low。。
首先就是筛法,把n个数的质因子种类数,和最小质因数维护出来。cnt[i]表示i的质因子有多少种,mi[i]表示i的最小质因数是多少
开一个vector 其中z[i]表示含有质因子i的数字的集合。
然后我们去进行两个数字的匹配,这里去贪心的选择。
首先我们应该倒序 即从z[n]到z[1]里面去选择。为什么? 因为含有的质因子越大,可以匹配到的另一个的个数越少,所以优先倒序来。
对于具体到某个z[i] 这里还需要一次贪心,比如 z[2][0]=2,z[2][1]=6,z[2][2]=8,z[2][3]=10 对z[2]排序应该是这样的 2 8 10 6
对于一个数的质因子的种类越多,能匹配的个数也越多,所以对于具体的z[i] 应该先按照质因子种类数从小到大排序,对于质因子种类数相同的,最小质因数越大,我们就优先对他进行匹配。
总体复杂度O(T * nlogn)

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
#define int long long
bool vis[maxn];
vector<int> z[maxn],qq;
int cnt[maxn],mi[maxn];
bool cmp(int x,int y){
    if(cnt[x]==cnt[y]) return mi[x]>mi[y];
    return cnt[x]<cnt[y];
}
signed main()
{

    int t;cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        qq.clear();
        for(int i=1; i<=n; i++)
            vis[i]=0,z[i].clear(),cnt[i]=0,mi[i]=1e9;
        for(int i=2;i<=n;i++){
            if(!vis[i]){
                for(int j=i;j<=n;j+=i){
                    vis[j]=1;
                    mi[j]=min(mi[j],i);
                    cnt[j]++;
                    z[i].push_back(j);
                }
            }
        }
        for(int i=1;i<=n;i++) vis[i]=0;
        int ans=0;
        for(int i=n; i; i--)
        {
            sort(z[i].begin(),z[i].end(),cmp);
            int a=-1,b=-1;
            for(int j=0; j<z[i].size(); j++)
            {
                if(!vis[z[i][j]])
                {
                    if(a==-1)
                    {
                        a=z[i][j];
                    }
                    else if(b==-1)
                    {
                        b=z[i][j];
                    }
                }
                if(a!=-1 && b!=-1)
                {
                    qq.push_back(a);
                    qq.push_back(b);
                    ans++;
                    vis[a]=vis[b]=1;
                    a=b=-1;
                }
            }
        }
        cout<<ans<<endl;
        for(int i=0; i<ans; ++i)
            cout<<qq[2*i]<<" "<<qq[2*i+1]<<endl;

    }
    return 0;
}