easy版本里是枚举x,然后找到abgcd(ab,x)\dfrac{ab}{gcd(ab,x)}gcd(ab,x)ab
显然y∣gy|gy∣g。
因为ab∣xyab|xyab∣xy,那么令g=gcd(ab,x),k1g=ab,k2g=xg=gcd(ab,x),k_1g=ab,k_2g=xg=gcd(ab,x),k1g=ab,k2g=x
k1∣k2yk_1|k_2yk1∣k2y,gcd(k1,k2)=1gcd(k_1,k_2)=1gcd(k1,k2)=1。因此k1∣yk_1|yk1∣y
枚举k1k_1k1的倍数即可找到yyy。
那么对于hard,瓶颈在于找xxx,但是注意到我们的关键是找gcd(ab,x)gcd(ab,x)gcd(ab,x)。
那么显然我们可以枚举ababab的因子,这里我们用n\sqrt{n}n分别枚举aaa的因子a′a'a′,bbb的因子b′b'b′,注意到10910^9109内最大因子个数为134413441344。因此双重循环复杂度完全够。
我们枚举k1=a′b′k_1=a'b'k1=a′b′ ,然后判两个数是否在范围内即可。
#include
using namespace std;
typedef long long ll;ll i,j,k,n,m,t,a,b,c,d,r1,r2;int main(){cin>>t;while(t--){cin>>a>>b>>c>>d;vector v1,v2;for(i=1;i*i<=a;i++){if(!(a%i)){v1.push_back(i);v1.push_back(a/i);}}for(i=1;i*i<=b;i++){if(!(b%i)){v2.push_back(i);v2.push_back(b/i);}}for(auto i:v1)for(auto j:v2){k=i*j;r1=(a/k+1)*k;if(r1>c)continue;r2=(b/(a*b/k)+1)*(a*b/k);if(r2>d)continue;cout<