2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem(把1到n分为不互质的数对,找最多的对数)

2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem(把1到n分为不互质的数对,找最多的对数)_第1张图片
2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem(把1到n分为不互质的数对,找最多的对数)_第2张图片
题目大意:把1到n分为不互质的数对,找最多的对数

思路:先从最大的质因数开始找,因为小的比大的更容易匹配,所以贪心的从大的开始找。
首先要预处理出所以数的最大质因数。
然后根据质因数从大往小找,当质因数大于n/2的时候 就找不到 配对了。
估计是偶数 直接配对,如果是奇数 讲2*p留出来,这样留到最后,这些数必定有2的公因子。
代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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 second

using 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()
{
    ios
    int T;
    cin>>T;
    get_primes(N);
    //T=1;
    while(T--)
    {
        solve();
    }
    return 0;
}

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