#include <cstdio>
#include <cstring>
#include <cstdlib>
typedef unsigned long long ULL;
const ULL M31 = (1ULL << 31) - 1;
// palindrom: a1 a2 a3 a4 a3 a2 a1
// forward hash: a1*b^6 + a2*b^5 + ... a2*b^1+ a1*b^0
// backward hash: a1*b^0 + a2*b^1 + ... + a2*b^5 + a1*b^6
ULL mod_M31(ULL val)
{
val = (val & M31) + (val>>31);
return (val >= M31) ? val - M31 : val;
}
void hash_forward(ULL &hash, unsigned b, unsigned c)
{
hash = mod_M31(hash * b + c);
}
void hash_backward(ULL &hash, ULL &b_pow, unsigned b, unsigned c)
{
hash = mod_M31(hash + b_pow*c);
b_pow = mod_M31(b_pow * b);
}
int main() {
unsigned b1 = 31;
ULL b1_pow = 1;
unsigned b2 = 107;
ULL b2_pow = 1;
unsigned b3 = 104729;
ULL b3_pow = 1;
unsigned b4 = 611953;
ULL b4_pow = 1;
// forward, backward
ULL hash1f = 0;
ULL hash1b = 0;
ULL hash2f = 0;
ULL hash2b = 0;
ULL hash3f = 0;
ULL hash3b = 0;
ULL hash4f = 0;
ULL hash4b = 0;
int N;
scanf("%d\n", &N);
// int count = 0;
const int BUF_SIZE = 3*1<<20;
char buffer[BUF_SIZE+1];
while (fgets(buffer, BUF_SIZE, stdin))
{
for (int i = 0; 'a' <= buffer[i] && buffer[i] <= 'z'; ++i)
{
char c = buffer[i];
hash_forward(hash1f, b1, c - 'a');
hash_backward(hash1b, b1_pow, b1, c - 'a');
hash_forward(hash2f, b2, c - 'a');
hash_backward(hash2b, b2_pow, b2, c - 'a');
hash_forward(hash3f, b3, c - 'a');
hash_backward(hash3b, b3_pow, b3, c - 'a');
hash_forward(hash4f, b4, c - 'a');
hash_backward(hash4b, b4_pow, b4, c - 'a');
// count++;
}
}
/*
int count = (hash1f == hash1b ? 1:0) + (hash2f == hash2b ? 1:0) +
(hash3f == hash3b ? 1:0) + (hash4f == hash4b ? 1:0);
if (count != 0 && count != 4)
{
printf("ERROR %d\n", count);
return 1;
}
*/
puts((hash1f == hash1b && hash2f == hash2b &&
hash3f == hash3b && hash4f == hash4b) ? "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 | #include <cstdio> #include <cstring> #include <cstdlib> typedef unsigned long long ULL; const ULL M31 = (1ULL << 31) - 1; // palindrom: a1 a2 a3 a4 a3 a2 a1 // forward hash: a1*b^6 + a2*b^5 + ... a2*b^1+ a1*b^0 // backward hash: a1*b^0 + a2*b^1 + ... + a2*b^5 + a1*b^6 ULL mod_M31(ULL val) { val = (val & M31) + (val>>31); return (val >= M31) ? val - M31 : val; } void hash_forward(ULL &hash, unsigned b, unsigned c) { hash = mod_M31(hash * b + c); } void hash_backward(ULL &hash, ULL &b_pow, unsigned b, unsigned c) { hash = mod_M31(hash + b_pow*c); b_pow = mod_M31(b_pow * b); } int main() { unsigned b1 = 31; ULL b1_pow = 1; unsigned b2 = 107; ULL b2_pow = 1; unsigned b3 = 104729; ULL b3_pow = 1; unsigned b4 = 611953; ULL b4_pow = 1; // forward, backward ULL hash1f = 0; ULL hash1b = 0; ULL hash2f = 0; ULL hash2b = 0; ULL hash3f = 0; ULL hash3b = 0; ULL hash4f = 0; ULL hash4b = 0; int N; scanf("%d\n", &N); // int count = 0; const int BUF_SIZE = 3*1<<20; char buffer[BUF_SIZE+1]; while (fgets(buffer, BUF_SIZE, stdin)) { for (int i = 0; 'a' <= buffer[i] && buffer[i] <= 'z'; ++i) { char c = buffer[i]; hash_forward(hash1f, b1, c - 'a'); hash_backward(hash1b, b1_pow, b1, c - 'a'); hash_forward(hash2f, b2, c - 'a'); hash_backward(hash2b, b2_pow, b2, c - 'a'); hash_forward(hash3f, b3, c - 'a'); hash_backward(hash3b, b3_pow, b3, c - 'a'); hash_forward(hash4f, b4, c - 'a'); hash_backward(hash4b, b4_pow, b4, c - 'a'); // count++; } } /* int count = (hash1f == hash1b ? 1:0) + (hash2f == hash2b ? 1:0) + (hash3f == hash3b ? 1:0) + (hash4f == hash4b ? 1:0); if (count != 0 && count != 4) { printf("ERROR %d\n", count); return 1; } */ puts((hash1f == hash1b && hash2f == hash2b && hash3f == hash3b && hash4f == hash4b) ? "TAK" : "NIE"); return 0; } |
English