#include<iostream>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cstdio>
using namespace std;
/*枚舉兩個奇數加數,直接套用米勒羅賓素數測試方法模板判斷是否是素數。模板地址在另一個博客裏。*/
typedef unsigned long long ull;
typedef unsigned long long LL;
LL prime[6] = {2, 3, 5, 233, 331};
LL qmul(LL x, LL y, LL mod) { // 乘法防止溢出, 如果p * p不爆LL的話可以直接乘; O(1)乘法或者轉化成二進制加法
return (x * y - (long long)(x / (long double)mod * y + 1e-3) *mod + mod) % mod;
/*
LL ret = 0;
while(y) {
if(y & 1)
ret = (ret + x) % mod;
x = x * 2 % mod;
y >>= 1;
}
return ret;
*/
}
LL qpow(LL a, LL n, LL mod) {
LL ret = 1;
while(n) {
if(n & 1) ret = qmul(ret, a, mod);
a = qmul(a, a, mod);
n >>= 1;
}
return ret;
}
bool Miller_Rabin(LL p) {
if(p < 2) return 0;
if(p != 2 && p % 2 == 0) return 0;
LL s = p - 1;
while(! (s & 1)) s >>= 1;
for(int i = 0; i < 5; ++i) {
if(p == prime[i]) return 1;
LL t = s, m = qpow(prime[i], s, p);
while(t != p - 1 && m != 1 && m != p - 1) {
m = qmul(m, m, p);
t <<= 1;
}
if(m != p - 1 && !(t & 1)) return 0;
}
return 1;
}
int main()
{
ull n,i,q;
int t;
cin>>t;
while (t--) {
cin>>n;
if(n==4){
cout<<2<<" "<<2<<endl;
continue;
}
for(i=3;i<=n/2;i=i+2)
{
if(Miller_Rabin(i)==false) continue;
q=n-i;
if(Miller_Rabin(q))
{
cout<<i<<" "<<q<<endl;
break;
}
}
}
return 0;
}
B. Goldbach(快速判斷大素數)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.