Educational Codeforces Round 89 (Rated for Div. 2) 参与排名人数13281
[codeforces 1366D] Two Divisors 互质公式推导+线性筛素数
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1366/problem/D
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
D - Two Divisors | GNU C++17 | Accepted | 358 ms | 49200 KB |
题目大意:给出数值a,找到a的两个大于1的约数b,c,要求满足GCD(b+c,a)=1,若能找到,输出相应的约数b,c,若不能找到输出-1,-1
思路:若能找到GCD(c,b)=1,并且a=c*b^n,那么b,c就是满足条件的约数。
以下是证明过程:
已知:a=c*b^n,GCD(c,b)=1
1.公式简要推导(若有不明,请看之后的详细推导)如下
GCD(b,c)=1可得CGD(b+c,c)=1
GCD(c,b)=1可得GCD(b+c,b)=1可得GCD(b+c,b^n)=1
综上所述GCD(b+c,c*b^n)=1
即GCD(b+c,a)=1
2.公式详细推导如下
GCD(b,c)=1可得b=k2*c+r2,(0<r2<c)
b+c=k2*c+r2+c=(k2+1)+r2
可以看到GCD(b+c,c)=1
GCD(c,b)=1可得c=k1*b+r1,(0<r1<b)
b+c=b+k1*b+r=(k1+1)*b+r1
可以看到GCD(b+c,b)=1
可得GCD(b+c,b^n)=1
综上所述GCD(b+c,c*b^n)=1
即GCD(b+c,a)=1
AC代码如下
#include <cstdio>
#include <algorithm>
#define maxn 10000010
using namespace std;
int prime[maxn/10],pn,mp[maxn];//prime质数,mp合数
int a[500010],d1[500010],d2[500010];
void linear_shaker(int x){//线性筛素数
int i,j;
for(i=2;i<=x;i++){
if(!mp[i])prime[++pn]=i,mp[i]=i;
for(j=1;prime[j]*i<=x;j++){
mp[prime[j]*i]=prime[j];//记录合数的最小质因数
if(i%prime[j]==0)break;
}
}
}
int main(){
int n,i,x=0;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]),x=max(x,a[i]);
linear_shaker(x);
for(i=1;i<=n;i++){
d1[i]=d2[i]=-1,x=a[i];
while(x%mp[a[i]]==0)x/=mp[a[i]];
if(x>1)d1[i]=mp[a[i]],d2[i]=x;
}
for(i=1;i<=n;i++)printf("%d ",d1[i]);
printf("\n");
for(i=1;i<=n;i++)printf("%d ",d2[i]);
printf("\n");
return 0;
}