#include <cstdio> #include <cstdint> const int NP = 2; const uint64_t PRIMES[NP] = {2388301079LL, 643463321LL}; const uint64_t BASES[NP] = {57288479LL, 315683527LL}; const int XLEN = 3000000; char input[XLEN + 8]; uint64_t mod_pow(uint64_t x, uint64_t y, uint64_t p) { uint64_t res = 1; while (y > 0) { while ((y & 1) == 0) { y >>= 1; x = (x * x) % p; } y--; res = (res * x) % p; } return res; } int main () { int n; scanf("%d\n", &n); n = 0; uint64_t RBASES[NP]; uint64_t pwrs[NP]; uint64_t rpwrs[NP]; uint64_t theres[NP]; uint64_t backs[NP]; for (int i = 0; i < NP; ++i) { RBASES[i] = mod_pow(BASES[i], PRIMES[i] - 2, PRIMES[i]); pwrs[i] = 1; rpwrs[i] = 1; theres[i] = 0; backs[i] = 0; } uint64_t coeff = 0; char c; int x; while (1) { x = scanf("%c", &c); if (x <= 0) { break; } if (c < 'a' || c > 'z') { break; } if (n < XLEN) { input[n] = c; } ++n; coeff = (uint64_t)(c - 'a' + 1); for (int i = 0; i < NP; ++i) { theres[i] = (theres[i] + (coeff * pwrs[i]) % PRIMES[i]) % PRIMES[i]; backs[i] = (backs[i] + (coeff * rpwrs[i]) % PRIMES[i]) % PRIMES[i]; pwrs[i] = (pwrs[i] * BASES[i]) % PRIMES[i]; rpwrs[i] = (rpwrs[i] * RBASES[i]) % PRIMES[i]; } } if (n < XLEN - 8) { for (int i = 0; i < n; ++i) { if (input[i] != input[n - 1 - i]) { printf("NIE\n"); return 0; } } printf("TAK\n"); return 0; } for (int i = 0; i < NP; ++i) { if (theres[i] != (backs[i] * mod_pow(BASES[i], (uint64_t)(n - 1), PRIMES[i])) % PRIMES[i]) { printf("NIE\n"); return 0; } } printf("TAK\n"); 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 | #include <cstdio> #include <cstdint> const int NP = 2; const uint64_t PRIMES[NP] = {2388301079LL, 643463321LL}; const uint64_t BASES[NP] = {57288479LL, 315683527LL}; const int XLEN = 3000000; char input[XLEN + 8]; uint64_t mod_pow(uint64_t x, uint64_t y, uint64_t p) { uint64_t res = 1; while (y > 0) { while ((y & 1) == 0) { y >>= 1; x = (x * x) % p; } y--; res = (res * x) % p; } return res; } int main () { int n; scanf("%d\n", &n); n = 0; uint64_t RBASES[NP]; uint64_t pwrs[NP]; uint64_t rpwrs[NP]; uint64_t theres[NP]; uint64_t backs[NP]; for (int i = 0; i < NP; ++i) { RBASES[i] = mod_pow(BASES[i], PRIMES[i] - 2, PRIMES[i]); pwrs[i] = 1; rpwrs[i] = 1; theres[i] = 0; backs[i] = 0; } uint64_t coeff = 0; char c; int x; while (1) { x = scanf("%c", &c); if (x <= 0) { break; } if (c < 'a' || c > 'z') { break; } if (n < XLEN) { input[n] = c; } ++n; coeff = (uint64_t)(c - 'a' + 1); for (int i = 0; i < NP; ++i) { theres[i] = (theres[i] + (coeff * pwrs[i]) % PRIMES[i]) % PRIMES[i]; backs[i] = (backs[i] + (coeff * rpwrs[i]) % PRIMES[i]) % PRIMES[i]; pwrs[i] = (pwrs[i] * BASES[i]) % PRIMES[i]; rpwrs[i] = (rpwrs[i] * RBASES[i]) % PRIMES[i]; } } if (n < XLEN - 8) { for (int i = 0; i < n; ++i) { if (input[i] != input[n - 1 - i]) { printf("NIE\n"); return 0; } } printf("TAK\n"); return 0; } for (int i = 0; i < NP; ++i) { if (theres[i] != (backs[i] * mod_pow(BASES[i], (uint64_t)(n - 1), PRIMES[i])) % PRIMES[i]) { printf("NIE\n"); return 0; } } printf("TAK\n"); return 0; } |