https://codeforces.ml/contest/1366/problem/D
(题目链接如上↑)
题解:
1.首先,gcd(x,y)=gcd(x+y,x*y)
证明如下:
gcd有两点性质:
(1) gcd(a,b)=gcd(a-b,b),gcd(a,b)=gcd(a+b,b)
(2) 若gcd(a,c)=1,则gcd(a,bc)=gcd(a,b)
下面正式开始证明:
由性质1可得: gcd(x,y)=1 -> gcd(x+y,y)=1
由性质2可得: gcd(x+y,xy)=gcd(x+y,x)
再由性质1可得: gcd(x+y,x)=gcd(y,x)=1
故:gcd(x+y,x*y)=gcd(x,y)=1
2.由唯一分解定理,可构造 d1 = q1 ^ k1 , d2 =q2 ^ k2… qn ^ kn
那么,(d1+d2)%p1!=0,……(d1+d2)%pn!=0
故(d1+d2)和ai互质。
3.这题数据的范围为1e7,所以需用欧拉筛,先找出1e7范围内的最小质因数。
线性筛模板:
int prime[1100000],primesize;
bool isprime[11000000];
void getlist(int listsize){
memset(isprime,1,sizeof(isprime));
isprime[1]=false;
for(int i=2;i<=listsize;i++){
if(isprime[i])prime[++primesize]=i;
for(int j=1;j<=primesize&&i*prime[j]<=listsize;j++) {
isprime[i*prime[j]]=false;
if(i%prime[j]==0) break;//保证了每个合数只会被它的最小素因子筛掉,就把复杂度降到了O(N)
}
}
}
AC代码:
#include <iostream>
using namespace std;
const int maxa=10000005,maxn=500005;
int prime[maxa],minprime[maxa];
int a[maxn],b1[maxn],b2[maxn];
int euler(int n){
int c=0;
for(int i=2;i<=n;i++){
if(!minprime[i]) prime[++c]=i,minprime[i]=i;
for(int j=1;j<=c&&i*prime[j]<=n;j++){
minprime[i*prime[j]]=prime[j];
if(i%prime[j]==0) break;
}
}
return c;
}
int main(){
int n;
cin>>n;
euler(1e7);
for(int i=0;i<n;i++){
cin>>a[i];
int x=a[i];
int now,mi=minprime[x];
while(x%mi==0){
x/=mi; now*=mi;
}
if(x!=1&&now!=1){
b1[i]=mi; b2[i]=x;
}
else{
b1[i]=-1; b2[i]=-1;
}
}
for(int i=0;i<n;i++){
if(i==0) cout<<b1[i];
else cout<<" "<<b1[i];
}
cout<<endl;
for(int i=0;i<n;i++){
if(i==0) cout<<b2[i];
else cout<<" "<<b2[i];
}
cout<<endl;
return 0;
}