#include <cstdio> #define read getchar_unlocked typedef unsigned long long hash; typedef unsigned int hash32; const hash Mersenne = (1ull << 61) - 1; inline hash M(const hash value, const hash mod) { return (value >= mod) ? (value%mod) : value; } //https://codeforces.com/blog/entry/60442 hash MultiplyMersenne(const hash a, const hash b) { hash l1 = (hash32)a, h1 = a >> 32, l2 = (hash32)b, h2 = b >> 32; hash l = l1 * l2, m = l1 * h2 + l2 * h1, h = h1 * h2; hash ret = (l&Mersenne) + (l >> 61) + (h << 3) + (m >> 29) + (m << 35 >> 3) + 1; ret = (ret & Mersenne) + (ret >> 61); ret = (ret & Mersenne) + (ret >> 61); return ret - 1; } hash ModMersenne(const hash a) { if (a < Mersenne) return a; hash l1 = (hash32)a, h1 = a >> 32; hash ret = (l1&Mersenne) + (l1 >> 61) + (h1 >> 29) + (h1 << 35 >> 3) + 1; ret = (ret & Mersenne) + (ret >> 61); ret = (ret & Mersenne) + (ret >> 61); return ret - 1; } struct RollingHashContainer { hash Base = 1; hash Mod = 1; hash Ascending = 0; hash AscendingBase = 1; hash Descending = 0; void Add(hash c) { c -= 'a'; Ascending = M(Ascending+ (c * AscendingBase), Mod); Descending = M(Descending*Base, Mod) + c; AscendingBase = M(AscendingBase*Base, Mod); } const bool Verify() { Descending = M(Descending, Mod); Ascending = M(Ascending, Mod); return Ascending == Descending; } RollingHashContainer() {} RollingHashContainer(hash base, hash mod) :Base(base), Mod(mod) {} }; struct MersenneHashContainer { hash Base = 1; hash Ascending = 0; hash AscendingBase = 1; hash Descending = 0; void Add(hash c) { c -= 'a'; Ascending = ModMersenne(MultiplyMersenne(c, AscendingBase) + Ascending); Descending = MultiplyMersenne(Descending, Base) + c; AscendingBase = MultiplyMersenne(AscendingBase, Base); } const bool Verify() { Ascending = ModMersenne(Ascending); Descending = ModMersenne(Descending); return Ascending == Descending; } MersenneHashContainer() {} MersenneHashContainer(hash base) :Base(base){} }; char Buffer[256]; RollingHashContainer First(37, 4e9 + 7u); MersenneHashContainer Second(29); int main() { fgets(Buffer, 255, stdin); char c; while ((c = read()) != EOF) { if (c == '\n') continue; First.Add(c); Second.Add(c); } if (First.Verify() && Second.Verify()) { printf("TAK\n"); } else { printf("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 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 <cstdio> #define read getchar_unlocked typedef unsigned long long hash; typedef unsigned int hash32; const hash Mersenne = (1ull << 61) - 1; inline hash M(const hash value, const hash mod) { return (value >= mod) ? (value%mod) : value; } //https://codeforces.com/blog/entry/60442 hash MultiplyMersenne(const hash a, const hash b) { hash l1 = (hash32)a, h1 = a >> 32, l2 = (hash32)b, h2 = b >> 32; hash l = l1 * l2, m = l1 * h2 + l2 * h1, h = h1 * h2; hash ret = (l&Mersenne) + (l >> 61) + (h << 3) + (m >> 29) + (m << 35 >> 3) + 1; ret = (ret & Mersenne) + (ret >> 61); ret = (ret & Mersenne) + (ret >> 61); return ret - 1; } hash ModMersenne(const hash a) { if (a < Mersenne) return a; hash l1 = (hash32)a, h1 = a >> 32; hash ret = (l1&Mersenne) + (l1 >> 61) + (h1 >> 29) + (h1 << 35 >> 3) + 1; ret = (ret & Mersenne) + (ret >> 61); ret = (ret & Mersenne) + (ret >> 61); return ret - 1; } struct RollingHashContainer { hash Base = 1; hash Mod = 1; hash Ascending = 0; hash AscendingBase = 1; hash Descending = 0; void Add(hash c) { c -= 'a'; Ascending = M(Ascending+ (c * AscendingBase), Mod); Descending = M(Descending*Base, Mod) + c; AscendingBase = M(AscendingBase*Base, Mod); } const bool Verify() { Descending = M(Descending, Mod); Ascending = M(Ascending, Mod); return Ascending == Descending; } RollingHashContainer() {} RollingHashContainer(hash base, hash mod) :Base(base), Mod(mod) {} }; struct MersenneHashContainer { hash Base = 1; hash Ascending = 0; hash AscendingBase = 1; hash Descending = 0; void Add(hash c) { c -= 'a'; Ascending = ModMersenne(MultiplyMersenne(c, AscendingBase) + Ascending); Descending = MultiplyMersenne(Descending, Base) + c; AscendingBase = MultiplyMersenne(AscendingBase, Base); } const bool Verify() { Ascending = ModMersenne(Ascending); Descending = ModMersenne(Descending); return Ascending == Descending; } MersenneHashContainer() {} MersenneHashContainer(hash base) :Base(base){} }; char Buffer[256]; RollingHashContainer First(37, 4e9 + 7u); MersenneHashContainer Second(29); int main() { fgets(Buffer, 255, stdin); char c; while ((c = read()) != EOF) { if (c == '\n') continue; First.Add(c); Second.Add(c); } if (First.Verify() && Second.Verify()) { printf("TAK\n"); } else { printf("NIE\n"); } return 0; } |