题意: 给定数字 a , b , c ,d
寻找x , a<x<= c, 寻找 y , b<y <= d
且x*y % a*b == 0
思路:
从题目条件出发,tl给4s,a,b,c,d小于1e5,将区间[a,c]遍历不会T,暴力搜索x可行,但套两层循环暴力搜索x与y会T,故要根据x找出y。
将x*y % a*b == 0条件进行拆解,由数论基本定理: A%B==0 , 那么A的质因子集合包含B的质因子集合。
故当确定x时,a*b的一部分质因子便被x包含,我们只需要找出y,使y包含a*b的另一部分质因子。
eg:
a*b = p1*p2*p3*.......pn
x=p1*p2*p3
则我们需要找出y,使y的质因子包含p4*p5*....pn
此时再main函数外搓一个gcd求最大公约数函数,便能得出x和a*b共有的质因子连乘积
另x和a*b共有的质因子连乘积为m
则y为m的k倍,接下来就要求k,使b<k*m<=d
则我们只需要找出[b,d]中所有符合条件的y的最小值,使k*m恰好大于b即可,判断k*m <=d ?
假设 k*m == b , 则k == b/m
因为y > b ,故当m%b ==0, k =( b+m)/m
当m % b != 0 , k = (b+m-1)/m
#include <bits\stdc++.h>
using namespace std;
typedef int int_32;
#define int long long
int gcd(int a, int b) {
if (b == 0)return a;
if (a == 0) return b;
return gcd(b, a % b);
}
int_32 main(void) {
int t;
cin >> t;
while (t--) {
int a, b, c, d, fl = 1;
cin >> a >> b >> c >> d;
int x, y;
for (x = a + 1; x <= c; x++) {
//needFact y需要包含的因子连乘积
int needFact = a * b / gcd(x, a * b);
if (needFact > d)continue;
if (b % needFact == 0) y = (b + needFact) / needFact*needFact;
else y = ((b + needFact - 1) / needFact) * needFact;
if (y <= d) {
cout << x << ' ' << y << endl;
fl = 0;
break;
}
}
if (fl)cout << -1 << ' ' << -1 << endl;
}
}