【数学】gcd数论——cf1366D

/*
gcd(x,y)=1 可推出 gcd(x+y,xy)=1
    反证法:gcd(x+y,xy)=c,c>1,那么设x+y=ac,xy=bc
            由于xy互质,所以c必定一部分质因子px出自x,另一部分py出自y
            x+y=a*px*py,其中px*py>1,且(x,y)=1,这是不成立的
            假设不成立,所以c=1 
             
所以只要a[i]存在两个及以上质因子,p1^c1 * p2^c2 * ...
    就让x=p1^c1,y=a[i]/(p1^c1),就有gcd(x+y,a[i])=1 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 500005
#define maxn 10000005
#define ll long long
 
int prime[10000005],m;
bool vis[10000005];
vector<int>G[10000005];
void divide(int nn){
    int n=nn;
    for(int i=1;i<=m&& 1ll*prime[i]*prime[i]<=n;i++)
    {
        if(n%prime[i]==0)
        {
            G[nn].push_back(prime[i]);
            while(n%prime[i]==0)n/=prime[i];
        }
    }
    if(n>1)G[nn].push_back(n);
} 
void init(){
    for(int i=2;i<maxn;i++){
        if(!vis[i])
            prime[++m]=i; 
        for(int j=1;j<=m;j++){
            if(1ll*prime[j]*i>=maxn)break;
            vis[1ll*prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }
}
 
int d1[N],d2[N],a[N],n;
 
signed main(){
    init();
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    //n=70;
    //for(int i=1;i<=n;i++)a[i]=i;
    for(int i=1;i<=n;i++){
        if(!vis[a[i]]){
            d1[i]=d2[i]=-1;
            continue;
        }
        if(G[a[i]].size()==0)divide(a[i]);
        if(G[a[i]].size()<=1){
            d1[i]=d2[i]=-1;
            continue;
        }
        
        ll x=1,y=a[i];
        while(y%G[a[i]][0]==0)y/=G[a[i]][0],x*=G[a[i]][0];
        if(y>1 && x>1)d1[i]=x,d2[i]=y;
        else d1[i]=d2[i]=-1;
        
    }
    for(int i=1;i<=n;i++)printf("%d ",d1[i]);puts("");
    for(int i=1;i<=n;i++)printf("%d ",d2[i]);puts("");
}

 

posted on 2020-06-12 12:19  zsben  阅读(341)  评论(0编辑  收藏  举报

导航