do_while_true

一言(ヒトコト)

Miller–Rabin 素数测试

\(n\leq 2^{64}\) 即正确。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<bitset>
#define pb emplace_back
#define mp std::make_pair
#define fi first
#define se second
typedef long long ll;
typedef __int128 i128;
typedef long double ld;
typedef unsigned long long ull;
typedef std::pair<int, int> pii;
typedef std::vector<int> vi;
const ll mod = 998244353;
ll Add(ll x, ll y) { return (x+y>=mod) ? (x+y-mod) : (x+y); }
ll Mul(ll x, ll y) { return x * y % mod; }
ll Mod(ll x) { return x < 0 ? (x + mod) : (x >= mod ? (x-mod) : x); }
ll cadd(ll &x, ll y) { return x = (x+y>=mod) ? (x+y-mod) : (x+y); }
ll cmul(ll &x, ll y) { return x = x * y % mod; }
template <typename T> T Max(T x, T y) { return x > y ? x : y; }
template<typename T, typename... T2> T Max(T x, T2 ...y) { return Max(x, y...); }
template <typename T> T Min(T x, T y) { return x < y ? x : y; }
template<typename T, typename... T2> T Min(T x, T2 ...y) { return Min(x, y...); }
template <typename T> T cmax(T &x, T y) { return x = x > y ? x : y; }
template <typename T> T cmin(T &x, T y) { return x = x < y ? x : y; }
template <typename T>
T &read(T &r) {
	r = 0; bool w = 0; char ch = getchar();
	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
	return r = w ? -r : r;
}
template<typename T1, typename... T2>
void read(T1 &x, T2& ...y) { read(x); read(y...); }
const int test[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 34};
i128 qpow(i128 x, i128 y, i128 mod) {
	i128 s = 1;
	while(y) {
		if(y & 1) s = s * x % mod;
		x = x * x % mod;
		y >>= 1;
	}
	return s;
}
bool Test(ll n, ll testnum) {
	int t = 0; ll x = n-1;
	while(!(x&1)) x >>= 1, ++t;
	i128 a = qpow(testnum, x, n);
	if(a == 1) return 1;
	for(int i = 0; i < t; ++i) {
		i128 lst = a;
		a = a * a % n;
		if(a == 1) return lst == n-1;
	}
	return 0;
}
bool check(ll x) {
	if(x < 2) return 0;
	for(auto a : test) if(x % a == 0) return x == a;
	for(auto a : test)
		if(!Test(x, a))
			return 0;
	return 1;
}
signed main() {
	ll x;
	while(~scanf("%lld", &x)) {
		putchar(check(x) ? 'Y' : 'N');
		putchar('\n');
	}
	return 0;
}
posted @ 2022-02-07 22:03  do_while_true  阅读(40)  评论(0编辑  收藏  举报