結果

問題 No.577 Prime Powerful Numbers
ユーザー vjudge1
提出日時 2025-04-18 21:58:21
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 376 ms / 2,000 ms
コード長 2,318 bytes
コンパイル時間 1,298 ms
コンパイル使用メモリ 163,256 KB
実行使用メモリ 7,848 KB
最終ジャッジ日時 2025-04-18 21:58:25
合計ジャッジ時間 2,989 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 10
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
using u64 = unsigned long long;
using u128 = __uint128_t;

u64 modmul(u64 a, u64 b, u64 mod) {
    return (u128)a * b % mod;
}

u64 modpow(u64 a, u64 e, u64 mod) {
    u128 res = 1, base = a % mod;
    while (e) {
        if (e & 1) res = (res * base) % mod;
        base = (base * base) % mod;
        e >>= 1;
    }
    return (u64)res;
}

bool isPrime(u64 n) {
    if (n < 2) return false;
    for (u64 p : {2ULL,3ULL,5ULL,7ULL,11ULL,13ULL,17ULL,19ULL,23ULL,29ULL,31ULL,37ULL}) {
        if (n % p == 0) return n == p;
    }
    u64 d = n - 1, s = 0;
    while ((d & 1) == 0) { d >>= 1; ++s; }
    for (u64 a : {2ULL, 325ULL, 9375ULL, 28178ULL, 450775ULL, 9780504ULL, 1795265022ULL}) {
        if (a % n == 0) continue;
        u64 x = modpow(a, d, n);
        if (x == 1 || x == n - 1) continue;
        bool composite = true;
        for (u64 r = 1; r < s; ++r) {
            x = modmul(x, x, n);
            if (x == n - 1) { composite = false; break; }
        }
        if (composite) return false;
    }
    return true;
}

u64 kthRoot(u64 n, int k) {
    if (k == 1) return n;
    long double approx = pow((long double)n, 1.0L/k);
    u64 x = (u64)(approx + 0.5);
    if (x < 2) x = 2;
    auto power = [&](u64 a) {
        u128 p = 1;
        for (int i = 0; i < k; ++i) {
            p *= a;
            if (p > n) break;
        }
        return p;
    };
    while (power(x) > n) --x;
    while (power(x + 1) <= n) ++x;
    return x;
}

bool isPrimePower(u64 n) {
    if (n < 2) return false;
    if (isPrime(n)) return true;
    for (int k = 2; k <= 60; ++k) {
        u64 r = kthRoot(n, k);
        if (r < 2) continue;
        u128 p = 1;
        for (int i = 0; i < k; ++i) {
            p *= r;
            if (p > n) break;
        }
        if (p == n && isPrime(r)) {
            return true;
        }
    }
    return false;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
	u64 T, x;
	cin >> T;
	while (T -- ) {
		cin >> x;
		if (x % 2 == 0) {
			if (x == 2) cout << "No\n";
			else cout << "Yes\n";
			continue;
		}
		int flag = 0;
		for (int i = 1; i < 60; i ++ )
			if ((1ll << i) <= x && isPrimePower(x - (1ll << i))) {
				cout << "Yes\n", flag = 1;
				break;
			}
		if (flag);
		else cout << "No\n";
	}
    return 0;
}
0