zoukankan      html  css  js  c++  java
  • Noip2009 Hankson 的趣味题 (简单数学)

    题意:n组询问,每组给定四个正整数a0,a1,b0,b1, 求满足gcd(x,a0) = a1, lcm(x,b0) = b1的x的个数。

    输入格式:

    第一行,一个正整数n;

    第二行,四个正整数a0,a1,b0,b1;

    输出格式:

    共n行,每行一个正整数,表示满足条件的x的个数。

    样例输入:

    2
    41 1 96 288
    95 1 37 1776

    样例输出:

    6
    2

    解析:一道简单的数学题。先来看一个简单的定理,gcd(a,b) = c, 则gcd(a/c,b/c) = 1. 定理的正确性很显然,在本题中,要求gcd(x,a0) = a1,即是gcd(x/a1,a0/a1) = 1。又要求lcm(x,b0)=b1,而lcm(x,b0) = x*b0/gcd(x,b0), 所以gcd(x,b0) = x*b0/lcm(x,b0). 因为lcm(x,b0) = b1,所以gcd(x,b0) = x*b0/b1. 同理,gcd(x/(x*b0/b1),b0/(x*b0/b1)) = 1,化简可得gcd(b1/b0,b1/x) = 1. 推到了这里,我们得到了两个式子,即gcd(x/a1,a0/a1) = 1,gcd(b1/b0,b1/x) = 1。可以发现x为a1的倍数,并且为b1的因数。所以我们只需要枚举b1的每个因子,再进行判断便可,复杂度o(n√b1)。

    代码如下:

    #include<cstdio>
    #include<cmath>
    using namespace std;
    
    int n,a0,a1,b0,b1,ans;
    
    int read(void) {
        char c; while (c=getchar(),c<'0' || c>'9'); int x=c-'0';
        while (c=getchar(),c>='0' && c<='9') x=x*10+c-'0'; return x;
    }
    
    int gcd(int x,int y) {  //求gcd 
        if (y==0) return x; else return gcd(y,x%y);
    }
    
    int main() {
        n=read();
          while (n--) {
              ans=0;
              a0=read(); a1=read(); b0=read(); b1=read();
                for (int i=1;i<=sqrt(b1);++i) {  //枚举每个因数 
                  if (!(b1%i)) {  //如果是i是b1的因数 
                    if (gcd(b1/b0,b1/i)==1 && i%a1==0 && gcd(i/a1,a0/a1)==1) ans++;
                    if (i==b1/i) continue;  //如果因数i与b1/i相等,就continue,防止重复计算 
                    if (gcd(b1/b0,i)==1 && (b1/i)%a1==0 && gcd(b1/i/a1,a0/a1)==1) ans++;
                  }
                }
              printf("%d
    ",ans);
          }
        return 0;
    }
  • 相关阅读:
    HTML5
    PHP
    eclipse项目导入到android studio
    Jpush教材
    Android性能优化典范
    Fresco好案例
    扫二维码关注微信号,回复“送礼包”就送超值大礼!
    Android开源项目大全之工具库
    android学习“知乎”建议
    C# Json时间类型的转换
  • 原文地址:https://www.cnblogs.com/Gaxc/p/9526289.html
Copyright © 2011-2022 走看看