• CF-1445 C


    题意

    给定一个 (p (ple 10^{18})), 一个 (q(q le 10^9)), 要找到一个最大的 (x) 满足:

    1. (p \%x = 0)
    2. (q \% x eq 0)

    分析

    直接枚举 (p) 的因数不可取,复杂度为 (O(sqrt p))。需要另辟蹊径。

    容易发现,若 (p\%q eq 0) ,那么答案即为 (p)

    接下来考虑 (p\%q = 0) 的情况。

    考虑到唯一分解的定理对于任意一个大于 1 的数字 n 都有

    [n = q_1^{c_1}q_2^{c_2}cdots q_n^{c_n} ]

    其中 (q_i)(n) 的质因数,(c_i) 为其指数。

    如果一个整数 (n) 不能被 (m) 整除,那么肯定有一个质数 (e),它在 (n) 中的指数小于在 (m) 中的指数。例如 (12 = 2^2*3^1)(8 = 2^3 * 3^0)

    然后我们枚举这个 (e),它必定是 (q) 的一个质因数,所以我们枚举 (q) 的质因子 (e),然后不断的让 (p) 除以 (e),直到 (p\%q eq 0),此时的 (p) 就是满足题目要求的 (x),最后在所有的情况中取一个最大的 (x) 即可。

    单组询问复杂度 (O(sqrt q))

    int T;
    ll p, q;
    
    ll gcd(ll a, ll b){
        return b == 0 ? a : gcd(b, a % b);
    }
    void solve(ll t){
        ll res = 0;
        // 枚举 q 的质因数
        for(int i = 2; i * i <= t;i++){
            if(t % i) continue;
            ll now = p; // 尝试不断的用 i 去除 p, 直到 p % q != 0
            while(now % q == 0) now /= i;
            while(t % i == 0) t /= i; 
            res = max(res, now);
        }
        if(t > 1){ // 质因数分解的最后一步
            ll now = p;
            while(now % q == 0) now /= t;
            res = max(res, now);
        }
        printf("%lld
    ", res);
    }
    int main(){
        cin >> T;
        while(T--){
            scanf("%lld%lld", &p, &q);
            if(p % q == 0) {
                solve(q);
            } else {
                printf("%lld
    ", p);
            }
        }
        return 0;
    }
    

    贴一下官方题解,原理与上述一致。

  • 相关阅读:
    一个java的进销存管理系统源码阅读
    嵌入式起步
    java数据库操作有关的杂记
    VS 调试
    软件测试的原则
    黑盒测试与白盒测试
    Xmind快速入门(基本操作够用了)
    opt目录
    日志测试
    bug的前世今生
  • 原文地址:https://www.cnblogs.com/1625--H/p/13956157.html
Copyright © 2020-2023  润新知