计蒜客——Goldbach
- Goldbach
- 判断大素数
#include<cstdio>
#include<cstdlib>
using namespace std;
#define N 10000
typedef unsigned long long ll;
ll ModMul(ll a, ll b, ll n) { //快速积取模 a*b%n
ll ans = 0;
while(b) {
if(b & 1)
ans = (ans + a) % n;
a = (a + a) % n;
b >>= 1;
}
return ans;
}
ll ModExp(ll a, ll b, ll n) { //快速幂取模 a^b%n
ll ans = 1;
while(b) {
if(b & 1)
ans = ModMul(ans, a, n);
a = ModMul(a, a, n);
b >>= 1;
}
return ans;
}
bool miller_rabin(ll n) { //Miller-Rabin素数检测算法
ll i, j, a, x, y, t, u, s = 10;
if(n == 2)
return true;
if(n < 2 || !(n & 1))
return false;
for(t = 0, u = n - 1; !(u & 1); t++, u >>= 1); //n-1=u*2^t
for(i = 0; i < s; i++) {
a = rand() % (n - 1) + 1;
x = ModExp(a, u, n);
for(j = 0; j < t; j++) {
y = ModMul(x, x, n);
if(y == 1 && x != 1 && x != n - 1)
return false;
x = y;
}
if(x != 1)
return false;
}
return true;
}
//以上都是模板,以下为核心算法
int main()
{
ll n, t;
scanf("%llu",&t);
while(t--){
scanf("%llu", &n);
//通过数学规律可以发现第一个素数最大不超过10000
for(ll i = 1; i < N; i++){
if(miller_rabin(i) && miller_rabin(n-i)){
printf("%llu %llu\n",i, n-i);
break;
}
}
}
return 0;
}
参考:https://blog.csdn.net/a1097304791/article/details/81586513