1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| #include <iostream> #include <vector> #include <algorithm>
using namespace std;
typedef unsigned long long u64; typedef __int128_t u128;
namespace decompos { u64 power(u64 base, u64 exp, u64 mod) { u64 res = 1; u128 b = base % mod; while (exp > 0) { if (exp % 2 == 1) res = (u128)res * b % mod; b = (u128)b * b % mod; exp /= 2; } return res; }
bool isComposite(u64 a, u64 d, u64 n, u64 s) { u64 x = power(a, d, n); if (x == 1 || x == n - 1) return false; for (u64 r = 1; r < s; r++) { x = (u128)x * x % n; if (x == n - 1) return false; } return true; }
bool isPrime(u64 n) { if (n < 2) return false; if (n % 2 == 0) return n == 2; if (n % 3 == 0) return n == 3; u64 d = n - 1; u64 s = __builtin_ctzll(d); d >>= s; static const vector<u64> bases = {2, 3, 5, 7, 11, 13, 17, 19, 23}; for (u64 a : bases) { if (n <= a) break; if (isComposite(a, d, n, s)) return false; } return true; } }
inline u64 get_val(u64 r, u64 c) { if (r < 1 || c < 1 || c > r) return 0; return (r * (r - 1)) / 2 + c; }
int count_prime_neighbors(u64 r, u64 c) { int count = 0; for (int dr = -1; dr <= 1; ++dr) { for (int dc = -1; dc <= 1; ++dc) { if (dr == 0 && dc == 0) continue; u64 nr = r + dr, nc = c + dc; if (nr >= 1 && nc >= 1 && nc <= nr) { u64 nv = get_val(nr, nc); if (decompos::isPrime(nv)) count++; } } } return count; }
u64 S(u64 n) { u64 total_sum = 0; for (u64 c = 1; c <= n; ++c) { u64 p = get_val(n, c); if (!decompos::isPrime(p)) continue;
vector<pair<u64, u64>> prime_neighbors; for (int dr = -1; dr <= 1; ++dr) { for (int dc = -1; dc <= 1; ++dc) { if (dr == 0 && dc == 0) continue; u64 nr = n + dr, nc = c + dc; if (nr >= 1 && nc >= 1 && nc <= nr) { u64 nv = get_val(nr, nc); if (decompos::isPrime(nv)) { prime_neighbors.push_back({nr, nc}); } } } }
if (prime_neighbors.size() >= 2) { total_sum += p; } else if (prime_neighbors.size() == 1) { u64 qr = prime_neighbors[0].first; u64 qc = prime_neighbors[0].second; bool q_is_center = false; for (int ddr = -1; ddr <= 1 && !q_is_center; ++ddr) { for (int ddc = -1; ddc <= 1; ++ddc) { if (ddr == 0 && ddc == 0) continue; u64 nnr = qr + ddr, nnc = qc + ddc; if (nnr == n && nnc == c) continue; if (nnr >= 1 && nnc >= 1 && nnc <= nnr) { if (decompos::isPrime(get_val(nnr, nnc))) { q_is_center = true; break; } } } } if (q_is_center) total_sum += p; } } return total_sum; }
int main() {
u64 n1 = 5678027; u64 n2 = 7208785;
u64 res1 = S(n1); cout << "S(" << n1 << ") = " << res1 << endl;
u64 res2 = S(n2); cout << "S(" << n2 << ") = " << res2 << endl;
cout << "Total Sum: " << res1 + res2 << endl;
return 0; }
|