[NOI Online 2022 普及组] 数学游戏 - 题解

场外选手口胡题解

题目大意

  • \(t\) 组数据,每组数据给定 \(x, z\),构造最小的 \(y\) 使得 \(z = x \times y \times \gcd(x, y)\),无解则输出 \(-1\)
  • \(1 \leq t \leq 5 \times 10^5\)\(1 \leq x \leq 10^9\)\(1 \leq z < 2^{63}\)

解题思路

首先判无解。容易发现如果 \(z\) 不是 \(x\) 的倍数显然无解。

接下来我们将题目中所给的式子做第一步化简:

\[y \times \gcd(x, y) = \frac zx \]

我们发现 \(\gcd(x, y)\) 不太方便化简,那就把它设出来吧。

不妨设 \(\gcd(x, y) = k\)\(x = k \times n\)\(y = k \times m\),我们有

\[(k \times m) \times k = k^2 \times m = \frac zx \]

所以 \(k^2 \mid \frac zx\)

考虑到 \(x = k \times n\),我们易得 \(k^2 \mid x^2\)

\(\therefore k^2 \mid \gcd(x^2, \frac zx)\)

似乎有些进展不下去了。那我们来大胆的猜测:有没有可能这个 \(\gcd(x^2, \frac zx)\) 就恰好等于 \(k^2\) 呢?

推柿子,可以得到

\[\gcd(x^2, \frac zx) = \gcd((k \times n)^2, k \times y) = \gcd(k^2 \times n^2, k^2 \times m) = \gcd(n^2, m) \times k^2 \]

注意到 \(n, m\) 互质,所以 \(k^2 = \gcd(x^2, \frac zx)\),我们可以愉快地求出 \(k\) 啦!

当然,我们需要判断一下,如果 \(\gcd(x^2, \frac zx)\) 不是完全平方数则无解。

再次观察我们最初得到的式子,\(y \times \gcd(x, y) = \frac zx\)

既然我们已经知道了 \(\frac zx\),知道了 \(k\) 也就是 \(\gcd(x, y)\),那么问题也迎刃而解了,

\[y = \frac zx \div \gcd(x, y) = \frac zx \div \sqrt{\gcd(x^2, \frac zx)} \]

单次询问时间复杂度 \(O(1)\)


代码

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

int t, x, z, num;

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

inline int read() {
	int x = 0; char ch = getchar();
	while (!isdigit(ch)) ch = getchar();
	while (isdigit(ch)) x = (x<<3) + (x<<1) + ch - '0', ch = getchar();
	return x;
}

signed main() {
	t = read();
	while (t--) {
		x = read(), z = read(), num = (int)sqrt(gcd(x*x, z/x));

		if (z%x || num*num != gcd(x*x, z/x)) {
			printf("-1\n");
			continue;
		}
		
		printf("%lld\n", z/x/num);
	}
}
posted @ 2022-03-26 21:57  Sparkle_ZH  阅读(214)  评论(2)    收藏  举报