[数论] Codeforces 1499D The Number of Pairs

题目大意

(T) 组询问,每组询问给定三个整数 (c,d,x)

问有多少对 ((a,b)) 使得 (c imes mathrm{lcm}(a,b) - d imes gcd(a,b)=x)

((1leq tleq 10^4,1leq c,d,xleq 10^7))

题解

[c imes mathrm{lcm}(a,b) - d imes 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 imes gcd(a,b)),其中

[r=prod_{i=1}^m p_i^{|k_i-k_i'|} ]

所以将 (mathrm{lcm}(a,b)=rgcd(a,b)) 代入原式,可得

[crgcd(a,b)-dgcd(a,b)=x ]

整理后可得

[gcd(a,b)=frac{x}{cr-d} ]

(c,d,x) 都是已知的,所以我们只需要枚举 (x) 的所有因子 (k),判断是否有 (k+dequiv 0pmod c),然后我们知道了整数 (r),设 (r) 的质因子数目为 (g(r)),则 (2^{g(r)}) 就是满足 (mathrm{lcm}(a,b)=rgcd(a,b))((a,b)) 对数。

显然 (g(r)) 可以线性筛。然后枚举 (x) 的所有因子的时间复杂度是 (O(sqrt x)) 的,共有 (T) 组数据,因此时间复杂度为线性筛的复杂度加上 (O(Tsqrt 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;
}
原文地址:https://www.cnblogs.com/AEMShana/p/14583182.html