zoukankan      html  css  js  c++  java
  • [数论] 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;
    }
    
  • 相关阅读:
    Python实现将IP地址转换为数字
    转 python两个 list 获取交集,并集,差集的方法
    并发编程之协程
    网络编程之协议
    网络编程
    python之路-模块和包
    python IO模型
    python 线程(队列,线程池),协程(理论greenlet,gevent模块,)
    python 线程(部分)Thread的使用,守护线程,互斥锁,递归锁,信号量,事件,条件,定时器
    常见的面试题
  • 原文地址:https://www.cnblogs.com/AEMShana/p/14583182.html
Copyright © 2011-2022 走看看