[数论] Codeforces 1499D The Number of Pairs
题目大意
有 \(T\) 组询问,每组询问给定三个整数 \(c,d,x\)
问有多少对 \((a,b)\) 使得 \(c\times \mathrm{lcm}(a,b) - d\times \gcd(a,b)=x\)
\((1\leq t\leq 10^4,1\leq c,d,x\leq 10^7)\)
题解
\[c\times \mathrm{lcm}(a,b) - d\times \gcd(a,b)=x\\
\]
由算术基本定理
\[a=\prod_{i=1}^m p_i^{k_i},b=\prod_{i=1}^m p_i^{k_i'},
\]
\(p_i\) 是互异素数。
则
\[\mathrm{lcm}(a,b)=\prod_{i=1}^{m}p_i^{\max\{k_i,k_i'\}}\\
\gcd(a,b)=\prod_{i=1}^{m}p_i^{\min\{k_i,k_i'\}}\\
\]
所以 \(\mathrm{lcm}(a,b)\) 必可以表示成 \(r\times \gcd(a,b)\),其中
\[r=\prod_{i=1}^m p_i^{|k_i-k_i'|}
\]
所以将 \(\mathrm{lcm}(a,b)=r\gcd(a,b)\) 代入原式,可得
\[cr\gcd(a,b)-d\gcd(a,b)=x
\]
整理后可得
\[\gcd(a,b)=\frac{x}{cr-d}
\]
\(c,d,x\) 都是已知的,所以我们只需要枚举 \(x\) 的所有因子 \(k\),判断是否有 \(k+d\equiv 0\pmod c\),然后我们知道了整数 \(r\),设 \(r\) 的质因子数目为 \(g(r)\),则 \(2^{g(r)}\) 就是满足 \(\mathrm{lcm}(a,b)=r\gcd(a,b)\) 的 \((a,b)\) 对数。
显然 \(g(r)\) 可以线性筛。然后枚举 \(x\) 的所有因子的时间复杂度是 \(O(\sqrt x)\) 的,共有 \(T\) 组数据,因此时间复杂度为线性筛的复杂度加上 \(O(T\sqrt x)\)。
Code
#include <bits/stdc++.h>
using namespace std;
#define RG register int
#define LL long long
vector<int> Prime;
bool not_Prime[20000005];
int f[20000010];
int c, d, x;
int T;
inline void Get_Prime(int Len) {
not_Prime[1] = true;
for (int i = 2;i <= Len;i++) {
if (!not_Prime[i]) { Prime.push_back(i);f[i] = 1; }
for (int j = 0;j < Prime.size();++j) {
int mid = Prime[j] * i;
if (mid > Len) break;
not_Prime[mid] = true;
if (i % Prime[j] == 0) { f[mid] = f[i];break; }
f[mid] = f[i] + 1;
}
}
return;
}
inline LL calc(LL r) { return 1LL << f[r]; }
void solve() {
LL i, res = 0;
for (i = 1;i * i < x;++i) {
if (x % i == 0) {
if ((i + d) % c == 0) res += calc((i + d) / c);
if ((x / i + d) % c == 0) res += calc((x / i + d) / c);
}
}
if (i * i == x) {
if ((i + d) % c == 0) res += calc((i + d) / c);
}
cout << res << endl;
}
int main() {
Get_Prime(20000000);
cin >> T;
while (T--) {
cin >> c >> d >> x;
solve();
}
return 0;
}