Ultra Weak Goldbach's Conjecture (Gym - 102055L)
题意:
问是否能够把整数N表示为六个素数之和的形式。如果能,给出任一种答案。
题解:
根据哥德巴赫猜想,大约等于4的偶数必然可以被表示为两个素数之和。
所以我们就有了下面两种方法:
-
2 2 2 + 大素数 + 一个大于等于4的偶数
-
2 2 3 + 大素数 + 一个大于等于4的偶数
可以先找出小于等于(N-(2+2+2+4))或者(N-(2+2+3+4))的那个大素数,减去后看剩下的部分的奇偶性,根据奇偶性来确定用(2 2 2)还是(2 2 3),以此来保证减去后剩下的数一定是个偶数。
然后暴力把剩下的那个偶数拆分成两个两个素数之和就好了(上面找的那个大素数是靠近N的,所以剩下的这个偶数肯定不会很大)。
判定素数如果暴力的话跑了(1762ms),上了(Miller\_Rabin)素性检测时间锐减到(93ms)。
代码
#include <bits/stdc++.h>
#define fopi freopen("in.txt", "r", stdin)
#define fopo freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
LL mult(LL a, LL b, LL p) {
a %= p;
b %= p;
LL res = 0, tmp = a;
while(b) {
if (b & 1) {
res += tmp;
if (res > p) res -= p;
}
tmp <<= 1;
if (tmp > p) tmp -= p;
b >>= 1;
}
return res;
}
LL quick_pow(LL a, LL b, LL p) {
LL res = 1;
LL tmp = a % p;
while(b) {
if (b & 1) res = mult(res, tmp, p);
tmp = mult(tmp, tmp, p);
b >>= 1;
}
return res;
}
bool check(LL a, LL n, LL x, LL t) {
LL res = quick_pow(a, x, n);
LL last = res;
for (LL i = 1; i <= t; i++) {
res = mult(res, res, n);
if (res == 1 && last != 1 && last != n-1) return true;
last = res;
}
return res != 1;
}
bool Miller_Rabin(LL n) {
if (n < 2) return false;
if (n == 2) return true;
if ((n & 1) == 0) return false;
LL x = n-1;
LL t = 0;
while ((x & 1) == 0) {
x >>= 1;
t++;
}
srand(time(NULL));
const LL tims = 8;
for (LL i = 0; i < tims; i++) {
LL a = rand() % (n-1) + 1;
if (check(a, n, x, t)) return false;
}
return true;
}
pair<LL, LL> Goldbach(LL res) {
for (LL i = 2; i <= res-2; i++)
if (Miller_Rabin(i) && Miller_Rabin(res-i)) return {i, res-i};
}
int T;
LL n;
int main() {
scanf("%d", &T);
for (int ca = 1; ca <= T; ca++) {
scanf("%lld", &n);
printf("Case %d: ", ca);
if (n <= 11) {
printf("IMPOSSIBLE
");
continue;
}
LL x = n-10;
if (!Miller_Rabin(x) || x % 2) while(!Miller_Rabin(x)) x--;
LL res = n-x;
if (res % 2 == 0) {
printf("2 2 2 %lld ", x);
res -= 6;
auto p = Goldbach(res);
printf("%lld %lld
", p.first, p.second);
} else {
printf("2 2 3 %lld ", x);
res -= 7;
auto p = Goldbach(res);
printf("%lld %lld
", p.first, p.second);
}
}
}