2020牛客暑期多校训练营(第四场) H-Harder Gcd Problem

题目链接

思路:

用埃氏筛从3开始,从小到大选因子,最小质因子相同的两两配对,如果最小质因子相同的数的个数为奇数时,就将质因子的二倍拿出,最后将所有拿出的质因子再次配对即可(拿出的数之间的gcd至少为2)。

代码:

#include
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=2e5+7;
const double eps=1e-8;
const int mod=1e9+7;
const int inf=0x7fffffff;
const double pi=3.1415926535;
using namespace std;
int vis[200010];
int p[200010],f[200010],tot;
struct Node
{
    int a,b;
};
void seive(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!f[i])
        {
            p[tot++]=i;
        }
        for(int j=0;j<tot&&i*p[j]<=n;j++)
        {
            f[i*p[j]]=1;
            if(i%p[j]==0)
            {
                break;
            }
        }
    }
}
vector<Node>ans;
signed main()
{
    IOS;
    seive(200000);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            vis[i]=0;
        }
        ans.clear();
        Node t;
        t.a=t.b=0;
        int i=0;
        while(i<tot&&2*p[i]<=n)
        {
            i++;
        }
        i--;
        while(i>=0)
        {
            int x=p[i];
            t.a=x;
            vis[x]=1;
            for(int j=n/x;j;j--)
            {
                if(vis[x*j])
                {
                    continue;
                }
                vis[x*j]=1;
                if(!t.a)
                {
                    t.a=x*j;
                }
                else
                {
                    t.b=x*j;
                    ans.push_back(t);
                    t.a=t.b=0;
                }
            }
            vis[t.a]=0;
            t.a=0;
            i--;
        }
        cout<<ans.size()<<endl;
        for(int i=0;i<ans.size();i++)
        {
            cout<<ans[i].a<<" "<<ans[i].b<<endl;
        }
    }
    return 0;
}

你可能感兴趣的:(数学,思维)