CF1336D Two Divisors 题解(gcd性质)

题目链接

题目大意

给你一个长度为\(n(n\le5e5)\)的数组\(a(2\le a[i] \le 1e7)\)

对于每个\(a[i]\)要你找到\(a[i]\)的两个因子\(x,y\)使得\(\gcd(x+y,a[i])=1\)

找不到输出\(-1\),找到任意输出一组解

题目思路

一个性质题

\(\gcd(x,y)=1\),则\(\gcd(x+y,x\times y)=1\)

证明如下

\(\gcd(x,y)=1\)\(\gcd(x+y,y)=1\)

\(\gcd(x+y,x\times y)=\gcd(x+y,y)\)

\(\gcd(x+y,x\times y)=1\)

那么这个题目先对其进行质因子分解

\(a[i]=p_1^{q_1}\times p_2^{q_2}.....\)

\(a[i]\)只能分解成一个质因子显然没有答案

若能分解成多个质因子

则能构造\(x=p_1^{q_1},y=\frac{a[i]}{p_1^{q_1}}\)

那么显然\(x,y\)互质

\(\gcd(x,y)=\gcd(x+y,x\times y)=1\)

发现没正好满足\(\gcd(x+y,a[i])=1\)

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=5e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
int n;
int a[maxn];
int ans1[maxn],ans2[maxn];
int prime[10000001],cnt;
int isprime[10000001];
void getprime(int n){
    for(ll i=2;i<=n;i++){//开ll因为后面要计算i*prime[j]
        if(!isprime[i]){
            prime[++cnt]=i;
            isprime[i]=i;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
            isprime[i*prime[j]]=prime[j];
            if(i%prime[j]==0) break;
        }
    }
}
signed main(){
    getprime(10000000);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        int mi=isprime[a[i]];
        ans1[i]=1;
        while(isprime[a[i]]==mi){
            ans1[i]=ans1[i]*mi;
            a[i]=a[i]/mi;
        }
        if(a[i]==1){
            ans1[i]=ans2[i]=-1;
        }else{
            ans2[i]=a[i];
        }
    }
    for(int i=1;i<=n;i++) printf("%d%c",ans1[i],i==n?'\n':' ');
    for(int i=1;i<=n;i++) printf("%d%c",ans2[i],i==n?'\n':' ');
    return 0;
}


posted @ 2021-04-13 21:11  hunxuewangzi  阅读(62)  评论(0编辑  收藏  举报