結果

問題 No.577 Prime Powerful Numbers
ユーザー minamiminami
提出日時 2019-04-04 12:33:25
言語 C++14
(gcc 13.2.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 3,049 bytes
コンパイル時間 1,517 ms
コンパイル使用メモリ 165,604 KB
実行使用メモリ 12,144 KB
最終ジャッジ日時 2023-08-26 19:24:45
合計ジャッジ時間 7,996 ms
ジャッジサーバーID
(参考情報)
judge13 / judge12
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 TLE -
testcase_01 -- -
testcase_02 -- -
testcase_03 -- -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
using u128 = long long;
#else
#define dump(...)
using u128 = __uint128_t;
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = 1'000'000'007;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

// 累乗
// O(log e)
// mod^2 が T の最大値より大きければオーバーフローするので掛け算に modmul を使う
template<typename T>
T modpow(T a, T e, T mod) {
	T res = 1;
	while (e > 0) {
		if (e & 1)res = res * a % mod; // modmul(res, a, mod);
		a = a * a % mod; // modmul(a, a, mod);
		e >>= 1;
	}
	return res;
}

// 素数判定(Miller-Rabin primality test)
// 2^24程度から
// millerRabinPrimalityTest(n, 5)
// modmul は遅いので極力使わない __uint128_t や BigInt を使う
// Verified: https://yukicoder.me/submissions/335299
//using u128 = __uint128_t;
template<typename T>
bool millerRabinPrimalityTest(T n, int iteration = 5) {
	if (n < 2)return false;
	if (n == 2)return true;
	if (n % 2 == 0)return false;
	T d = n - 1;
	while (d % 2 == 0)d /= 2;
	for (int i = 0; i < iteration; i++) {
		T a = rand() % (n - 1) + 1, t = d;
		T mod = modpow(a, t, n);
		while (t != n - 1 && mod != 1 && mod != n - 1) {
			mod = mod * mod % n; //modmul(mod, mod, n);
			t *= 2;
		}
		if (mod != n - 1 && t % 2 == 0)return false;
	}
	return true;
}

template<typename T>
bool isPrimePower(T n, int iteration = 5) {
	dump(n);
	int t = n, R = 0;
	while (t) {
		R++;
		t >>= 1;
	}
	dump(R);
	for (int r = 1; r <= R; r++) {
		dump(r);
		auto f = [&](int x) {
			int k = r;
			T y = 1;
			while (k) {
				if (y * x > n)return true; // オーバーフロー対策
				if (k & 1) y *= x;
				x *= x;
				k >>= 1;
			}
			return y >= n;
		};
		auto binarySearch = [&](T ng, T ok) {
			if (f(ng))return ng;
			while (ng + 1 < ok) {
				int m = (ng + ok) / 2;
				if (f(m))
					ok = m;
				else
					ng = m;
			}
			return ok;
		};
		auto power = [&](T a, int k) {
			T r = 1;
			while (k) {
				if (k & 1) r *= a;
				a *= a;
				k >>= 1;
			}
			return r;
		};
		T p = binarySearch(T(2), n + 1);
		dump(p);
		if (power(p, r) != n)continue;
		if (millerRabinPrimalityTest(p, iteration))
			return true;
	}
	return false;
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int Q; cin >> Q;
	rep(_, 0, Q) {
		long long N; cin >> N;
		if (N % 2 == 0) {
			cout << "Yes" << endl;
		}
		else {
			bool yes = false;
			rep(b, 1, 64) {
				long long q = 1LL << b;
				if (N - 3 < q)break;
				long long p = N - q;
				if (isPrimePower(u128(p))) {
					yes = true;
					break;
				}
			}
			if (yes) {
				cout << "Yes" << endl;
			}
			else {
				cout << "No" << endl;
			}
		}
	}

	return 0;
}
0