NOIP2009Hankson的趣味题

题目戳这里

分析


1.gcd


gcd(x,a0)=a1
{x=k1a1a0=k2a1

gcd(k1,k2)=1

简单证明:

假设 gcd(k1,k2)1

K=gcd(k1,k2)(K1)
{k1=pKk2=qK
{x=pKa1a0=qKa1
gcd(x,a0)=Ka1a1

这个结论与题目条件不符,所以 gcd(k1,k2)=1 成立

结合开始的式子,化简,得到 gcd(x/a1,a0/a1)=1

把这个结论推广一下,得到结论 P

对于两个正整数 a,b ,设 gcd(a,b)=k ,则存在 gcd(a/k,b/k)=1


2.lcm


lcm(x,b0)=b1
gcd(x,b0)=xb0/lcm(x,b0)=xb0/b1

由结论 P
gcd(x/(xb0/b1),b0/(xb0/b1))=1
化简得
gcd(b1/b0,b1/x)=1


3.gcd&&lcm


整理一下得到的重要的式子

{gcd(x/a1,a0/a1)=1gcd(b1/b0,b1/x)=1

用心体会这两个式子,发现 x a1 的整数倍且是 b1 的因子
这个好像由 gcd 和 lcm 也可以得到?嗯,就这样。
于是得到了一种解题思路

b1 枚举 b1 的因子(也就是 x ),如果这个数是 a1 的整数倍,并且满足那两个式子,ans++


code:

#include
using namespace std;
int gcd(int a,int b) {
    return b==0?a:gcd(b,a%b);
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int a0,a1,b0,b1;
        scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
        int p=a0/a1,q=b1/b0,ans=0;
        for(int x=1;x*x<=b1;x++) 
            if(b1%x==0){
                if(x%a1==0&&gcd(x/a1,p)==1&&gcd(q,b1/x)==1) ans++;
                int y=b1/x;//得到另一个因子
                if(x==y) continue; 
                if(y%a1==0&&gcd(y/a1,p)==1&&gcd(q,b1/y)==1) ans++;
            }
        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(OnlineJudge——洛谷,NOIP,数论,数论——gcd)