#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; } |
English