[NOIp2009] $Hankson$ 的趣味题

类型:数论

传送门:>Here<

题意:给出四个数$a_0,a_1,b_0,b_1$,求满足$gcd(x,a_0)=a_1,lcm(x,b_0)=b_1$的$x$的个数

解题思路

显然$a_1 | x, x|b_1$,因此设$x = a_1 * p, \ b_1 = x*q$。则$b_1 = a_1*p*q$

设$p*q=b_1/a_1=s$

$∵gcd(x,a_0)=a_1 \ ∴gcd(x/a_1,a_0/a_1)=1$

$∵lcm(x,b_0)=b_1 \ ∴gcd(b_1/x,b_1/b_0)=1$

由于$x/a_1=p,b_1/x=q=s/p$

$∴ \left\{\begin{matrix} gcd(p,a_0/a_1)=1\\ gcd(s/p,b_1/b_0)=1\\ \end{matrix}\right. $

由此我们发现,只需要枚举$s$的因子$p$进行验证即可,复杂度$O(\sqrt{s} * N)$

Code

特判完全平方数

/*By DennyQi 2018.8.17*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cmath>
#define  r  read()
#define  Max(a,b)  (((a)>(b)) ? (a) : (b))
#define  Min(a,b)  (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = 10010;
const int MAXM = 27010;
const int INF = 1061109567;
inline int read(){
    int x = 0; int w = 1; register int c = getchar();
    while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
    if(c == '-') w = -1, c = getchar();
    while(c >= '0' && c <= '9') x = (x<<3) + (x<<1) + c - '0', c = getchar();return x * w;
}
int n,m,a[2],b[2],p,s,T,lim,ans;
int gcd(int a, int b){
    return !b ? a : gcd(b, a%b);
}
inline bool judge(int s, int p){
    if(gcd(s/p, b[1]/b[0]) != 1) return 0;
    if(gcd(p, a[0]/a[1]) != 1) return 0;
    return 1;
}
int main(){
    T = r;
    while(T--){
        a[0] = r, a[1] = r;
        b[0] = r, b[1] = r;
        s = b[1] / a[1];
        ans = 0;
        lim = floor(sqrt(s));
        for(p = 1; p <= lim; ++p){
            if(s % p == 0){
                if(judge(s,p)) ++ans;
                if(s/p == p) continue;
                if(judge(s,s/p)) ++ans;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qixingzhi/p/9491486.html