結果

問題 No.577 Prime Powerful Numbers
ユーザー minamiminami
提出日時 2019-04-04 12:43:23
言語 C++14
(gcc 13.2.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 3,118 bytes
コンパイル時間 1,482 ms
コンパイル使用メモリ 166,256 KB
実行使用メモリ 4,380 KB
最終ジャッジ日時 2023-08-26 19:34:48
合計ジャッジ時間 3,305 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 4 ms
4,380 KB
testcase_01 AC 22 ms
4,380 KB
testcase_02 WA -
testcase_03 AC 70 ms
4,376 KB
testcase_04 AC 5 ms
4,376 KB
testcase_05 AC 381 ms
4,376 KB
testcase_06 AC 21 ms
4,380 KB
testcase_07 AC 387 ms
4,380 KB
testcase_08 AC 63 ms
4,376 KB
testcase_09 AC 61 ms
4,376 KB
testcase_10 AC 1 ms
4,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
using u128 = mp::cpp_int;
#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);
	T t = n, R = 0;
	while (t) {
		R++;
		t >>= 1;
	}
	dump(R);
	for (int r = 1; r <= R; r++) {
		auto f = [&](T 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) {
				T 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