这是我的 AC 代码
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define _rep(i, a, b) for (int i = a; i >= b; i--)
using namespace std;
typedef long long ll;
#define int ll
int prime[7] = {2, 3, 7, 13, 29, 37, 97};
int mul(int a, int b, int mod) {
int res = 0;
while (b) {
if (b & 1) res = (res + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return res % mod;
}
int qpow(int a, int b, int mod) {
int res = 1;
while (b) {
if (b & 1) res = mul(res, a, mod);
a = mul(a, a, mod);
b >>= 1;
}
return res % mod;
}
bool Miller_Rabin(int n, int a) {
int d = n - 1, r = 0;
while (n & 1 == 0) r++, n >>= 1;
int x = qpow(a, d, n);
if (x == 1) return true;
rep (i, 0, r - 1) {
if (x == n - 1) return true;
x = mul(x, x, n);
}
return false;
}
bool solve(int n) {
rep (i, 0, 6) {
if (n == prime[i]) return true;
//cout << n << " " << prime[i] << endl;
if (n % prime[i] == 0) return false;
//cout << n << " " << prime[i] << endl;
if (!Miller_Rabin(n, prime[i])) return false;
//cout << n << " " << prime[i] << endl;
}
return true;
}
signed main() {
int T; cin >> T;
while (T --> 0) {
int n; cin >> n;
if (solve(n)) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
但是如下一份代码无法通过,区别仅仅在于快速幂中没有使用龟速乘:
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define _rep(i, a, b) for (int i = a; i >= b; i--)
using namespace std;
typedef long long ll;
#define int ll
int prime[7] = {2, 3, 7, 13, 29, 37, 97};
int mul(int a, int b, int mod) {
int res = 0;
while (b) {
if (b & 1) res = (res + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return res % mod;
}
int qpow(int a, int b, int mod) {
int res = 1;
while (b) {
if (b & 1) res = (res * a) % mod
a = (a * a) % mod;
b >>= 1;
}
return res % mod;
}
bool Miller_Rabin(int n, int a) {
int d = n - 1, r = 0;
while (n & 1 == 0) r++, n >>= 1;
int x = qpow(a, d, n);
if (x == 1) return true;
rep (i, 0, r - 1) {
if (x == n - 1) return true;
x = mul(x, x, n);
}
return false;
}
bool solve(int n) {
rep (i, 0, 6) {
if (n == prime[i]) return true;
//cout << n << " " << prime[i] << endl;
if (n % prime[i] == 0) return false;
//cout << n << " " << prime[i] << endl;
if (!Miller_Rabin(n, prime[i])) return false;
//cout << n << " " << prime[i] << endl;
}
return true;
}
signed main() {
int T; cin >> T;
while (T --> 0) {
int n; cin >> n;
if (solve(n)) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}