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
| #include <bits/stdc++.h> using namespace std;
using i128 = __int128_t; using u128 = __uint128_t;
string s; i128 dp[20][170][2][2]; bool vis[20][170][2][2]; bool isPrime[170];
int len;
i128 dfs(int pos, int sum, bool tight, bool started) { if (pos == len) { if (started && isPrime[sum]) return 1; return 0; }
if (vis[pos][sum][tight][started]) return dp[pos][sum][tight][started];
vis[pos][sum][tight][started] = true; i128 &res = dp[pos][sum][tight][started]; res = 0;
int up = tight ? (s[pos] - '0') : 9;
for (int d = 0; d <= up; d++) { bool n_started = started || (d != 0); int n_sum = sum + (n_started ? d : 0); bool n_tight = tight && (d == up);
if (n_sum <= 162) res += dfs(pos + 1, n_sum, n_tight, n_started); } return res; }
i128 count_good(i128 x) { s.clear(); while (x > 0) { s.push_back('0' + (int)(x % 10)); x /= 10; } if (s.empty()) s = "0"; reverse(s.begin(), s.end()); len = s.size();
memset(vis, 0, sizeof(vis)); return dfs(0, 0, 1, 0); }
int main() { memset(isPrime, true, sizeof(isPrime)); isPrime[0] = isPrime[1] = false; for (int i = 2; i * i <= 162; i++) if (isPrime[i]) for (int j = i * i; j <= 162; j += i) isPrime[j] = false;
i128 target = 1; for (int i = 0; i < 16; i++) target *= 10;
i128 L = 1, R = (i128)1e18; while (L < R) { i128 mid = (L + R) >> 1; if (count_good(mid) >= target) R = mid; else L = mid + 1; }
string out; i128 ans = L; while (ans > 0) { out.push_back('0' + (int)(ans % 10)); ans /= 10; } reverse(out.begin(), out.end()); cout << out << "\n"; }
|