P1072 [NOIP2009 提高组] Hankson 的趣味题

P1072 [NOIP2009 提高组] Hankson 的趣味题

0x01 题意

给出(a_0,a_1,b_0,b_1),求(x)的个数使得:

  1. (x)(a_0)的最大公约数是(a_1).

  2. (x)(b_0)的最小公倍数是(b_1).

0x02 解

有一个定理是这样说的:

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

证明:显然

把俩条件变下型就成了

[egin{cases}gcd(x/a_1,a_0/a_1)=1\gcd(b_1/b_0,b_1/x)=1end{cases} ]

发现什么?

(x)既是(a_1)的倍数,还是(b_1)的因子

直接枚(b_1)的因子判是不是(a_1)的倍数并且满足俩式子就行了

0x03 码

#include<bits/stdc++.h>
using namespace std;

int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}

int main(){
	int t;
	cin>>t;
	while(t--){
		int a1,a0,b0,b1,ans=0;
		cin>>a0>>a1>>b0>>b1;
		
		int p=a0/a1,q=b1/b0;
		
		for(int i=1;i<=b1/i;i++)
			if(b1%i==0){
				if(i%a1==0&&gcd(i/a1,p)==1&&gcd(q,b1/i)==1) ans++;
				if(b1/i==i) continue;
				if((b1/i)%a1==0&&gcd((b1/i)/a1,p)==1&&gcd(q,b1/(b1/i))==1) ans++;
			}
				
		
		cout<<ans<<endl;
	}
	
	
	return 0;
}
原文地址:https://www.cnblogs.com/wsyunine/p/14457111.html