题目链接
题目大意
给你一个长度为(n(nle5e5))的数组(a(2le 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 imes y)=1)
证明如下
若(gcd(x,y)=1) 则(gcd(x+y,y)=1)
由(gcd(x+y,x imes y)=gcd(x+y,y))
则(gcd(x+y,x imes y)=1)
那么这个题目先对其进行质因子分解
(a[i]=p_1^{q_1} imes 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 imes 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?'
':' ');
for(int i=1;i<=n;i++) printf("%d%c",ans2[i],i==n?'
':' ');
return 0;
}