E2. Divisible Numbers (hard version)

E2. Divisible Numbers (hard version)

This is an hard version of the problem. The only difference between an easy and a hard version is the constraints on $a, b, c$ and $d$.

You are given $4$ positive integers $a, b, c, d$ with $a<c$ and $b<d$. Find any pair of numbers $x$ and $y$ that satisfies the following conditions:

  • $a < x \leq c$ , $b < y \leq d$,
  • $x \cdot y$ is divisible by $a \cdot b$.

Note that required $x$ and $y$ may not exist.

Input

The first line of the input contains a single integer $t$ $(1 \leq t \leq 10)$, the number of test cases.

The descriptions of the test cases follow.

The only line of each test case contains four integers $a, b, c$ and $d$ $(1 \leq a< c \leq {10}^{9}, 1 \leq b < d \leq {10}^{9})$.

Output

For each test case print a pair of numbers $a < x \leq c$ and $b < y \leq d$ such that $x \cdot y$ is divisible by $a \cdot b$. If there are multiple answers, print any of them. If there is no such pair of numbers, then print $\text{-1 -1}$.

Example

input

10
1 1 2 2
3 4 5 7
8 9 15 18
12 21 14 24
36 60 48 66
1024 729 373248 730
1024 729 373247 730
5040 40320 40319 1000000000
999999999 999999999 1000000000 1000000000
268435456 268435456 1000000000 1000000000

output

2 2
4 6
12 12
-1 -1
-1 -1
373248 730
-1 -1
15120 53760
-1 -1
536870912 536870912

 

解题思路

  参考easy version

  如果像easy version一样枚举$x$那么必然会超时。在easy version中,我们枚举$x$是为了得到$\gcd(x, a \cdot b)$,也就是$a \cdot b$的一个因子,而$\frac{a \cdot b}{\gcd(a \cdot b, x)}$就是$a \cdot b$的另外一个因子,然后根据这个因子的倍数去找到$y$($x$也是因子$\gcd(x, a \cdot b)$的倍数)。

  那么我们就可以想到能否枚举$a \cdot b$的所有因子,对于其中一对因子$a'$和$b'$($a' \cdot b' = a \cdot b$),假设$a' \mid x$,$b' \mid y$,如果在区间$[a+1, c]$存在$a'$的倍数,在区间$[b+1, d]$存在$b'$的倍数,那么就存在一组解。判断是否在区间存在某个数的倍数的方法和easy version中的一样,就是看一下大于左端点的最小的倍数是否不超过右端点。

  这里要枚举出所有$a \cdot b$的因子,感觉上好像会超时,实际上在不超过${10}^{9}$的数中,包含因子最多的那个数的因子个数为$1344$,意味着在${10}^{18}$范围内的数中,因子个数最多不超过${1344}^2$。

  因此我们可以先枚举出$a \cdot b$的因子中,所有不超过$c$的因子$t$,同时$t$还要满足$\frac{a \cdot b}{t} \leq d$。然后再遍历刚才得到的所有因子$d$,如果在区间$[a+1, c]$存在$d$的倍数,且在区间$[b+1, d]$存在$\frac{a \cdot b}{d}$的倍数,那么就存在一组解。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 LL a, b, c, d;
 7 LL m;
 8 unordered_map<int, int> mp;
 9 vector<pair<int, int>> p;
10 vector<int> ds;
11 
12 void divide(int x) { 
13     for (int i = 2; i <= x / i; i++) {
14         while (x % i == 0) {
15             mp[i]++;
16             x /= i;
17         }
18     }
19     if (x > 1) mp[x]++;
20 }
21 
22 void dfs(int u, LL prod) {
23     if (prod > c) return;    // 因子超过[a+1, c]这个范围 
24     if (u == p.size()) {
25         if (m / prod <= d) ds.push_back(prod);    // 另外一个因子超过[b+1, d]这个范围 
26         return;
27     }
28     LL t = 1;
29     for (int i = 0; i <= p[u].second; i++) {
30         dfs(u + 1, prod * t);
31         t *= p[u].first;
32     }
33 }
34 
35 void solve() {
36     mp.clear(), p.clear(), ds.clear();
37     cin >> a >> b >> c >> d;
38     m = a * b;
39     divide(a), divide(b);    // 质因数分解
40     for (auto &it : mp) {
41         p.push_back(it);
42     }
43     dfs(0, 1);    // 求a*b的因子 
44     for (int i = 0; i < ds.size(); i++) {
45         int x = ds[i], y = m / x;
46         x = (a / x + 1) * x, y = (b / y + 1) * y;
47         if (x <= c && y <= d) {    // 在区间范围内存在因子倍数 
48             printf("%d %d\n", x, y);
49             return;
50         }
51     }
52     printf("-1 -1\n");
53 }
54 
55 int main() {
56     int t;
57     scanf("%d", &t);
58     while (t--) {
59         solve();
60     }
61     
62     return 0;
63 }

 

参考资料

  Codeforces Round #828 (Div. 3) Editorial:https://codeforces.com/blog/entry/108101

posted @ 2022-10-19 20:12  onlyblues  阅读(83)  评论(0编辑  收藏  举报
Web Analytics