题目链接 https://nanti.jisuanke.com/t/25985
Description:
Goldbach’s conjecture is one of the oldest and best-known unsolved problems in number theory and all of mathematics. It states:
Every even integer greater than 2 can be expressed as the sum of two primes.
The actual verification of the Goldbach conjecture shows that even numbers below at least 1e14 can be expressed as a sum of two prime numbers.
Many times, there are more than one way to represent even numbers as two prime numbers.
For example, 18=5+13=7+11, 64=3+61=5+59=11+53=17+47=23+41, etc.
Now this problem is asking you to divide a postive even integer n (2
Input:
The first line of input is a T means the number of the cases.
Next T lines, each line is a postive even integer n (2
Output:
The output is also T lines, each line is two number we asked for.
T is about 100.
本题答案不唯一,符合要求的答案均正确
样例输入
1
8
样例输出
3 5
题解
给一个大于2的整数n,求两个质数a和b,使得n=a+b。
枚举a,则b=n-a,用米勒罗宾算法判断b是否为质数。
枚举a时小数据用欧拉筛,大数据暴力。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 2000000;
LL primee[maxn], notPrime[maxn], priCnt=0;
LL prime[6] = {2, 3, 5, 233, 331};
LL qmul(LL x, LL y, LL mod) {
return (x * y - (long long)(x / (long double)mod * y + 1e-3) *mod + mod) % mod;
}
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;
}
void getPrime() {
for (int i = 2; i < maxn; i++) {
if (!notPrime[i])
primee[priCnt++] = i;
for (int j = 0; j < priCnt && i * primee[j] < maxn; j++) {
notPrime[i * primee[j]] = 1;
if (i % primee[j] == 0) break;
}
}
}
int main() {
int t;
LL n;
getPrime();
scanf("%d", &t);
while (t--) {
scanf("%lld", &n);
int f = 0;
for (LL i = 0; i < priCnt; i++) {
if (Miller_Rabin(n - primee[i])) {
f = 1;
printf("%lld %lld\n", primee[i], n - primee[i]);
break;
}
}
if (f == 0) {
LL p=n/2;
if (p%2==0)p--;
for (;p>prime[priCnt-1];p-=2) {
if (Miller_Rabin(p) && Miller_Rabin(n-p)) {
printf("%lld %lld\n", p , n-p);
break;
}
}
}
}
return 0;
}