#include <cstdint>
#include <iostream>
using namespace std;
int64_t power(int64_t a, int64_t n, int64_t mod)
{
int64_t power = a;
int64_t result = 1;
while (n)
{
if (n & 1)
result = (result * power) % mod;
power = (power * power) % mod;
n >>= 1;
}
return result;
}
// n−1 = 2^s * d with d odd by factoring powers of 2 from n−1
bool witness(int64_t n, int64_t s, int64_t d, int64_t a)
{
int64_t x = power(a, d, n);
int64_t y;
while (s) {
y = (x * x) % n;
if (y == 1 && x != 1 && x != n - 1)
return false;
x = y;
--s;
}
if (y != 1)
return false;
return true;
}
/*
* if n < 1,373,653, it is enough to test a = 2 and 3;
* if n < 9,080,191, it is enough to test a = 31 and 73;
* if n < 4,759,123,141, it is enough to test a = 2, 7, and 61;
* if n < 1,122,004,669,633, it is enough to test a = 2, 13, 23, and 1662803;
* if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11;
* if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13;
* if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17.
*/
bool is_prime_mr(int64_t n)
{
if (((!(n & 1)) && n != 2) || (n < 2) || (n % 3 == 0 && n != 3))
return false;
if (n <= 3)
return true;
int64_t d = n / 2;
int64_t s = 1;
while (!(d & 1)) {
d /= 2;
++s;
}
if (n < 1373653)
return witness(n, s, d, 2) && witness(n, s, d, 3);
if (n < 9080191)
return witness(n, s, d, 31) && witness(n, s, d, 73);
if (n < 4759123141)
return witness(n, s, d, 2) && witness(n, s, d, 7) && witness(n, s, d, 61);
if (n < 1122004669633)
return witness(n, s, d, 2) && witness(n, s, d, 13) && witness(n, s, d, 23) && witness(n, s, d, 1662803);
if (n < 2152302898747)
return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11);
if (n < 3474749660383)
return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11) && witness(n, s, d, 13);
return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11) && witness(n, s, d, 13) && witness(n, s, d, 17);
}
const int64_t pows[] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000,
100000000000,
1000000000000,
10000000000000
};
bool validate(int64_t left, int64_t right)
{
return is_prime_mr(right) && is_prime_mr(left);
}
bool test(int64_t n)
{
int64_t right = 0;
int64_t pow_index = 0;
while(n > 0)
{
int64_t num = n % 10;
right += pows[pow_index] * num;
n /= 10;
pow_index++;
if(num != 0 && validate(n, right))
{
return true;
}
}
return false;
}
int main()
{
ios_base::sync_with_stdio(false);
int64_t num;
cin >> num;
cout << (test(num) ? "TAK" : "NIE");
return 0;
}
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 | #include <cstdint> #include <iostream> using namespace std; int64_t power(int64_t a, int64_t n, int64_t mod) { int64_t power = a; int64_t result = 1; while (n) { if (n & 1) result = (result * power) % mod; power = (power * power) % mod; n >>= 1; } return result; } // n−1 = 2^s * d with d odd by factoring powers of 2 from n−1 bool witness(int64_t n, int64_t s, int64_t d, int64_t a) { int64_t x = power(a, d, n); int64_t y; while (s) { y = (x * x) % n; if (y == 1 && x != 1 && x != n - 1) return false; x = y; --s; } if (y != 1) return false; return true; } /* * if n < 1,373,653, it is enough to test a = 2 and 3; * if n < 9,080,191, it is enough to test a = 31 and 73; * if n < 4,759,123,141, it is enough to test a = 2, 7, and 61; * if n < 1,122,004,669,633, it is enough to test a = 2, 13, 23, and 1662803; * if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11; * if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13; * if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17. */ bool is_prime_mr(int64_t n) { if (((!(n & 1)) && n != 2) || (n < 2) || (n % 3 == 0 && n != 3)) return false; if (n <= 3) return true; int64_t d = n / 2; int64_t s = 1; while (!(d & 1)) { d /= 2; ++s; } if (n < 1373653) return witness(n, s, d, 2) && witness(n, s, d, 3); if (n < 9080191) return witness(n, s, d, 31) && witness(n, s, d, 73); if (n < 4759123141) return witness(n, s, d, 2) && witness(n, s, d, 7) && witness(n, s, d, 61); if (n < 1122004669633) return witness(n, s, d, 2) && witness(n, s, d, 13) && witness(n, s, d, 23) && witness(n, s, d, 1662803); if (n < 2152302898747) return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11); if (n < 3474749660383) return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11) && witness(n, s, d, 13); return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11) && witness(n, s, d, 13) && witness(n, s, d, 17); } const int64_t pows[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000 }; bool validate(int64_t left, int64_t right) { return is_prime_mr(right) && is_prime_mr(left); } bool test(int64_t n) { int64_t right = 0; int64_t pow_index = 0; while(n > 0) { int64_t num = n % 10; right += pows[pow_index] * num; n /= 10; pow_index++; if(num != 0 && validate(n, right)) { return true; } } return false; } int main() { ios_base::sync_with_stdio(false); int64_t num; cin >> num; cout << (test(num) ? "TAK" : "NIE"); return 0; } |
English