D. Another Problem About Dividing Numbers

题意:a,b,k3个数。问a和b能否通过k次操作,让a和b相等。其中每次操作是选一个c能整除a或者b,然后a/c或者b/c。输出yes或者no。

思路:有点像图的问题,但是可以从质因子数量这一块入手。先线性筛,然后对于输入a和b,如果两个数的质因子数量 >= k,那么则可以通过刚好k次操作让他们都变成1。如果质因子数量和 < k,那么不可能变相等。另外,k > 60多的时候,也不可能变相等。因为对于最大输入1e9,最多只有29.几个质因子2。 还有,对于k = 1的情况要单独讨论,因为k = 1时,只有而且必须有一个数进行操作。此时ab中有一方需能被另一方整除,并且ab不相等才可以。

总结:思路有点模糊,也是写一步想一步,对于k =1的情况没有考虑到,是跑了测试样例才知道的。求出质因子数量后其他的就好说了,还是要考虑一下极端输入样例。

vector<int> prime_values;
bitset<33333> bs;

void sievePrimes(int x = 32222){
    bs.set();
    bs[0] = bs[1] = 0;
    for (int i = 2; i <= x; ++i){
        if (bs[i]){
            prime_values.emplace_back(i);
        }
        for (const auto& prime : prime_values){
            if (1ll * i * prime > x){
                break;
            }
            bs[i * prime] = 0;
            if (i % prime == 0){
                break;
            }
        }
    }
}

void preProcess(){
    sievePrimes();
}

void solve(){
    int a, b, k;
    cin >> a >> b >> k;

    if (k >= 65){
        cout << "No" << '\n';
    }
    else{
        multiset<int> prime_a;
        multiset<int> prime_b;
        auto getPrimes = [](multiset<int>& cur_set, int x) -> void{
            for (const auto& prime : prime_values){
                while (x % prime == 0){
                    x /= prime;
                    cur_set.insert(prime);
                }
            }
            if (x > 1){
                cur_set.insert(x);
            }
        };

        getPrimes(prime_a, a);
        getPrimes(prime_b, b);

        int sz_a = (int)prime_a.size();
        int sz_b = (int)prime_b.size();
        if (sz_a + sz_b < k){
            cout << "No\n";
        }
        else if (k == 1){
            if (a < b){swap(a, b);}
            if (a % b == 0 && a != b){
                cout << "Yes\n";
            }
            else{
                cout << "No\n";
            }
        }
        else{
            cout << "Yes\n";
        }
    }
}
posted @ 2024-05-07 09:42  _Yxc  阅读(17)  评论(0)    收藏  举报