基于费马小定理和二次探测定理
查看原帖
基于费马小定理和二次探测定理
964982
987654321logo楼主2024/8/14 17:16
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int base[100000000], num;
bool vis[1000000001];
ll qpow(ll a, ll b, const ll mod) {
	a %= mod;
	ll ans = 1;
	while (b) {
		if (b & 1) ans = (ans * a) % mod;
		a = (a * a) % mod;
		b >>= 1;
	}
	return ans;
}
bool winese(ll a, ll n) {
	ll u = n - 1;
	int t = 0;
	for (int i = 7; i >= 0; i--)
		if ((u & ((1 << i) - 1)) == 0) {
			u >>= i;
			t += i;
		}
	ll x1 = qpow(a, u, n);
	for (int i = 1; i <= t; i++) {
		ll x2 = (x1 * x1) % n;
		if (x2 == 1 && x1 != 1 && x1 != n - 1) return 1;
		x1 = x2;
	}
	return x1 != 1;
}
int prime(ll n) {
	for (int i = 1;i<=num; i++) if (n % base[i] == 0) return n == base[i];
	for (int i = 1; i<=num; i++) if (qpow(base[i], n - 1, n) != 1) return 0;
	for (int i = 1; i<=num; i++) if (winese(base[i], n))  return 0;
	for (int i = 1; (6 * i + 1) <= n / (6 * i + 1); i++) {
		if (n % (6 * i + 1) == 0) return 0;
		if (n % (6 * i + 5) == 0) return 0;
	}
	return 0;
}
int t;
ll n;
int main() {
	for (int i = 2; i <= 1000000; i++) {
		if (vis[i] == 0) base[++num] = i;
		for (int j = 1; j <= num && i * base[j] <= 1000000; j++) {
			vis[i * base[j]] = 1;
			if (i % base[j] == 0) break;
		}
	}
	cin >> n;
	cout << (prime(n) ? "YES" : "NO") << endl;
}
2024/8/14 17:16
加载中...