Educational Codeforces Round 106 - D. The Number of Pairs
题目链接
题意:
给定\(c,d,x\). 计算满足 $ c \cdot lcm(a, b) - d \cdot gcd(a, b) = x $ 的\((a, b)\)对数
思路:
记\(lcm(a,b)\)为lcm, \(gcd(a,b)\)为gcd. 显然\(lcm/gcd为\)整数,等式两边同除gcd
左边 \(= c * lcm / gcd - d\)
右边 \(= x / gcd\)
显然左边是整数减去整数为整数, 因此右边也是整数,
所以我们可以枚举x的因子即\(gcd\)枚举的时间复杂度为\(sqrt(n)\)
对于一个\(gcd\)要使等式成立必然有唯一的\(lcm\)满足, 因此问题转换为
已知两个数的\(lcm\)与\(gcd\),求多少对数满足条件, 对每对(gcd,lcm)的结果求和即使答案
对于子问题, 我们知道\(lcm/gcd\)的同一种素因子必然要么只在a, 要么只在b
反证法:假设对于一种素因子p, 在lcm中是\(p^{a+2}\),在gcd中是\(p^{a}\),那么在\(lcm/gcd\)中为\(p^2\)
如果p同时在a,b中, 那么gcd就会变大...
因此有\(2^{cnt[lcm/gcd]}\)对\((a,b)\)满足\(lcm(a,b),gcd(a,b)\)
说不清了
注意素数筛到2e7
const ll maxn = 2e7 + 7;
ll p[maxn], tot; //* p[0] = 2,p[1] = 3... tot为素数个数
bool vis[maxn]; //* vis[i] == 0 -> i为素数
ll t, n, c, d, x, cnt[maxn];
void init(int n = maxn - 1) // 1e7 -> 125ms
{
for (int i = 2; i <= n; i++) {
if (!vis[i])
p[tot++] = i;
for (int j = 0; j < tot; j++) {
if (p[j] * i > n)
break;
vis[p[j] * i] = 1;
if (i % p[j] == 0)
break;
}
}
for (ll i = 0; i < tot; i++) {
ll now = p[i];
for (ll mdf = 1; mdf * now < maxn; mdf++)
cnt[mdf * now]++;
}
}
ll solve(ll gc, ll lc) {
if (lc % gc)
return 0;
if (lc == gc)
return 1;
ll pp = lc / gc;
return (1LL << cnt[pp]);
}
void solve() {
cin >> t;
init();
while (t--) {
cin >> c >> d >> x;
ll ans = 0;
for (ll gc = 1; gc * gc <= x; gc++) {
if (x % gc)
continue;
ll gcd = gc;
if ((x + gcd * d) % c == 0) {
ll lcm = (x + gcd * d) / c;
ans += solve(gcd, lcm);
}
if (gc * gc == x)
continue;
gcd = x / gc;
if ((x + gcd * d) % c == 0) {
ll lcm = (x + gcd * d) / c;
ans += solve(gcd, lcm);
}
}
cout << ans << endl;
}
}
我看见 你

浙公网安备 33010602011771号