求问:为什么要用龟速乘
查看原帖
求问:为什么要用龟速乘
381949
Federico2903楼主2023/7/8 23:12

这是我的 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;
}
2023/7/8 23:12
加载中...