#include <cstdio>
#include <cstring>
#include <bitset>
#define DBG(...) fprintf(stderr, __VA_ARGS__)
typedef int I;
static const I MAXL = 20000000;
static const I BUFL = MAXL / 4 + 123;
static std::bitset<BUFL * 5> buf; // 3MB
static inline void ins(I pos, I c) {
if (pos > MAXL/2)
return;
I ix = (pos % BUFL) * 5;
for (I i=0; i<5; ++i)
buf[ix + i] = !!(c & (1u << i));
}
static inline I get(I pos) {
I ix = (pos % BUFL) * 5;
I ret = 0;
for (I i=0; i<5; ++i)
ret |= (buf[ix + i] << i);
return ret;
}
static inline bool next(I& i) {
I c = getchar();
if (c < 'a' || c > 'z')
return false;
i = c - 'a';
return true;
}
template <I d, I q>
struct rollinghash {
I left, right, h;
bool equal() const {
return left == right;
}
void init(I c1, I c2) {
h = 1;
left = c1 % q;
right = c2 % q;
}
void even(I c, I half) {
right = (d * (right + q - (h * half) % q) % q + c) % q;
}
void odd(I c, I half) {
h = (h * d) % q;
left = (left + (h * half) % q) % q;
right = ((right * d) % q + c) % q;
}
};
static bool check() {
rollinghash<32, 103> h1;
rollinghash<32, 83> h2;
{
I c1, c2;
if (!next(c1) || !next(c2))
return true;
ins(0, c1);
ins(1, c2);
h1.init(c1, c2);
h2.init(c1, c2);
}
for (I pos=2;; ++pos) {
I c;
if (!next(c))
return h1.equal() && h2.equal();
ins(pos, c);
I half = get(pos / 2);
if (pos & 1) {
h1.odd(c, half);
h2.odd(c, half);
} else {
h1.even(c, half);
h2.even(c, half);
}
}
}
int main() {
I N;
scanf("%u\n", &N);
printf(check() ? "TAK\n" : "NIE\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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | #include <cstdio> #include <cstring> #include <bitset> #define DBG(...) fprintf(stderr, __VA_ARGS__) typedef int I; static const I MAXL = 20000000; static const I BUFL = MAXL / 4 + 123; static std::bitset<BUFL * 5> buf; // 3MB static inline void ins(I pos, I c) { if (pos > MAXL/2) return; I ix = (pos % BUFL) * 5; for (I i=0; i<5; ++i) buf[ix + i] = !!(c & (1u << i)); } static inline I get(I pos) { I ix = (pos % BUFL) * 5; I ret = 0; for (I i=0; i<5; ++i) ret |= (buf[ix + i] << i); return ret; } static inline bool next(I& i) { I c = getchar(); if (c < 'a' || c > 'z') return false; i = c - 'a'; return true; } template <I d, I q> struct rollinghash { I left, right, h; bool equal() const { return left == right; } void init(I c1, I c2) { h = 1; left = c1 % q; right = c2 % q; } void even(I c, I half) { right = (d * (right + q - (h * half) % q) % q + c) % q; } void odd(I c, I half) { h = (h * d) % q; left = (left + (h * half) % q) % q; right = ((right * d) % q + c) % q; } }; static bool check() { rollinghash<32, 103> h1; rollinghash<32, 83> h2; { I c1, c2; if (!next(c1) || !next(c2)) return true; ins(0, c1); ins(1, c2); h1.init(c1, c2); h2.init(c1, c2); } for (I pos=2;; ++pos) { I c; if (!next(c)) return h1.equal() && h2.equal(); ins(pos, c); I half = get(pos / 2); if (pos & 1) { h1.odd(c, half); h2.odd(c, half); } else { h1.even(c, half); h2.even(c, half); } } } int main() { I N; scanf("%u\n", &N); printf(check() ? "TAK\n" : "NIE\n"); return 0; } |
English