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
#include <cstdio>
#include <cassert>
#include <algorithm>

static const int BUF_SIZE = 512 * 1024;
static char buf1[BUF_SIZE];
static char buf2[BUF_SIZE];

void readAtOffset(int offset, char *buf, int size)
{
	//printf("read at offset %d, size %d\n", offset, size);
	int res = fseek(stdin, offset, SEEK_SET);
	assert(res == 0);
	res = fread(buf, 1, size, stdin);
	assert(res == size);
}

bool areBuffersReverseEqual(int size)
{
	for (int i = 0; i < size; ++i) {
		if (buf1[i] != buf2[size-i-1])
			return false;
	}
	return true;
}

bool czyPalindrom(const int startOffset, const int endOffset)
{
	const int length = endOffset - startOffset;

	//printf("startOffset=%d endOffset=%d length=%d\n", startOffset, endOffset, length);

	for (int off = 0; off < length / 2; off += BUF_SIZE) {
		const int toCompare = std::min(length / 2 - off, BUF_SIZE);
		readAtOffset(startOffset + off, buf1, toCompare);
		readAtOffset(endOffset - off - toCompare, buf2, toCompare);
		if (!areBuffersReverseEqual(toCompare))
			return false;
	}
	return true;
}

int main()
{
	int ignoredLength;
	scanf("%d", &ignoredLength);
	char chr = fgetc(stdin);
	assert(chr == '\n');

	const int startOffset = ftell(stdin);
	fseek(stdin, -1, SEEK_END);
	const int endOffset = ftell(stdin);
	chr = fgetc(stdin);
	assert(chr == '\n');

	if (czyPalindrom(startOffset, endOffset))
		printf("TAK\n");
	else
		printf("NIE\n");
	return 0;
}