#include <cstdio> #include <set> #include <utility> #define REP(a, n) for (int a = 0; a < (n); ++a) #define FOR(a, b, c) for (int a = (b); a <= (c); ++a) #define FORD(a, b, c) for (int a = (b); a >= (c); --a) #define INF 1000000000 typedef long long LL; using namespace std; ////////////////////// #define DEBUG(x) //x int XS, YS, K; set<pair<int, int>> zebyLD, zebyPG; set<pair<int, int>> sr_xy, sr_yx; inline bool czyLD(int x, int y, set<pair<int, int>> &zeby = zebyLD) { return zeby.lower_bound(make_pair(x, 0))->second <= y; // pierwsza, której x jest >=x -> czy jej y jest <=y } void dodaj_zab_LD(int x, int y, set<pair<int, int>> &zeby = zebyLD) { for (;;) { auto it = zeby.upper_bound(make_pair(x, INF)); --it; if (it->second < y) break; zeby.erase(it); } zeby.emplace(x, y); } inline bool czyPG(int x, int y) { return czyLD(XS - x, YS - y, zebyPG); } inline void dodaj_zab_PG(int x, int y) { dodaj_zab_LD(XS - x, YS - y, zebyPG); } void rozszerzLD(int x, int y) { bool byl = false; int xmem, ymem; for (;;) { auto it = sr_xy.lower_bound(make_pair(x + 1, y)); // tylko do y, nie do y-1 if (it == sr_xy.end() || it->first > x + 1) break; if (!byl) { byl = true; // biore pierszego (najwyższego) xmem = it->first; ymem = it->second; } sr_yx.erase(make_pair(it->second, it->first)); sr_xy.erase(it); } if (byl) { dodaj_zab_LD(xmem, ymem); rozszerzLD(xmem, ymem); } byl = false; for (;;) { auto it = sr_yx.lower_bound(make_pair(y - 1, 0)); if (it == sr_yx.end() || *it > make_pair(y - 1, x + 1)) break; byl = true; // biore ostatniego (skrajnie prawego) ymem = it->first; xmem = it->second; sr_xy.erase(make_pair(it->second, it->first)); sr_yx.erase(it); } if (byl) { dodaj_zab_LD(xmem, ymem); rozszerzLD(xmem, ymem); } } void rozszerzPG(int x, int y) { bool byl = false; int xmem, ymem; for (;;) { auto it = sr_xy.lower_bound(make_pair(x - 1, 0)); if (it == sr_xy.end() || *it > make_pair(x - 1, y)) // tylko do y, nie do y + 1 break; byl = true; // biore ostatniego (najniższego) xmem = it->first; ymem = it->second; sr_yx.erase(make_pair(it->second, it->first)); sr_xy.erase(it); } if (byl) { dodaj_zab_PG(xmem, ymem); rozszerzPG(xmem, ymem); } byl = false; for (;;) { auto it = sr_yx.lower_bound(make_pair(y + 1, x - 1)); if (it == sr_yx.end() || it->first > y + 1) break; if (!byl) { byl = true; // biore pierwszego (skrajnie lewego) ymem = it->first; xmem = it->second; } sr_xy.erase(make_pair(it->second, it->first)); sr_yx.erase(it); } if (byl) { dodaj_zab_PG(xmem, ymem); rozszerzPG(xmem, ymem); } } int main() { scanf("%d%d%d", &XS, &YS, &K); int mod = 0; ++XS; // faktyczne pole: od 1 do XS - 1, dodatkowe pola: 0, XS ++YS; zebyLD.emplace(0, 0); zebyPG.emplace(0, 0); zebyLD.emplace(XS, YS); zebyPG.emplace(XS, YS); REP(a, K) { int x, y, zm; scanf("%d%d%d", &x, &y, &zm); x = (x ^ mod) % (XS - 1) + 1; y = (y ^ mod) % (YS - 1) + 1; bool ld = czyLD(x - 1, y + 1), pg = czyPG(x + 1, y - 1); if (ld && pg) { printf("TAK\n"); mod ^= zm; } else { printf("NIE\n"); if (!czyLD(x, y) && !czyPG(x, y)) { sr_xy.emplace(x, y); sr_yx.emplace(y, x); if (ld) rozszerzLD(x - 1, y + 1); if (pg) rozszerzPG(x + 1, y - 1); } } DEBUG( fprintf(stderr, "zęby LD:"); for (auto p : zebyLD) fprintf(stderr, " (%d,%d)", p.first, p.second); fprintf(stderr, "\nzęby PG:"); for (auto p : zebyPG) fprintf(stderr, " (%d,%d)", XS - p.first, YS - p.second); fprintf(stderr, "\n"); ) } }
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | #include <cstdio> #include <set> #include <utility> #define REP(a, n) for (int a = 0; a < (n); ++a) #define FOR(a, b, c) for (int a = (b); a <= (c); ++a) #define FORD(a, b, c) for (int a = (b); a >= (c); --a) #define INF 1000000000 typedef long long LL; using namespace std; ////////////////////// #define DEBUG(x) //x int XS, YS, K; set<pair<int, int>> zebyLD, zebyPG; set<pair<int, int>> sr_xy, sr_yx; inline bool czyLD(int x, int y, set<pair<int, int>> &zeby = zebyLD) { return zeby.lower_bound(make_pair(x, 0))->second <= y; // pierwsza, której x jest >=x -> czy jej y jest <=y } void dodaj_zab_LD(int x, int y, set<pair<int, int>> &zeby = zebyLD) { for (;;) { auto it = zeby.upper_bound(make_pair(x, INF)); --it; if (it->second < y) break; zeby.erase(it); } zeby.emplace(x, y); } inline bool czyPG(int x, int y) { return czyLD(XS - x, YS - y, zebyPG); } inline void dodaj_zab_PG(int x, int y) { dodaj_zab_LD(XS - x, YS - y, zebyPG); } void rozszerzLD(int x, int y) { bool byl = false; int xmem, ymem; for (;;) { auto it = sr_xy.lower_bound(make_pair(x + 1, y)); // tylko do y, nie do y-1 if (it == sr_xy.end() || it->first > x + 1) break; if (!byl) { byl = true; // biore pierszego (najwyższego) xmem = it->first; ymem = it->second; } sr_yx.erase(make_pair(it->second, it->first)); sr_xy.erase(it); } if (byl) { dodaj_zab_LD(xmem, ymem); rozszerzLD(xmem, ymem); } byl = false; for (;;) { auto it = sr_yx.lower_bound(make_pair(y - 1, 0)); if (it == sr_yx.end() || *it > make_pair(y - 1, x + 1)) break; byl = true; // biore ostatniego (skrajnie prawego) ymem = it->first; xmem = it->second; sr_xy.erase(make_pair(it->second, it->first)); sr_yx.erase(it); } if (byl) { dodaj_zab_LD(xmem, ymem); rozszerzLD(xmem, ymem); } } void rozszerzPG(int x, int y) { bool byl = false; int xmem, ymem; for (;;) { auto it = sr_xy.lower_bound(make_pair(x - 1, 0)); if (it == sr_xy.end() || *it > make_pair(x - 1, y)) // tylko do y, nie do y + 1 break; byl = true; // biore ostatniego (najniższego) xmem = it->first; ymem = it->second; sr_yx.erase(make_pair(it->second, it->first)); sr_xy.erase(it); } if (byl) { dodaj_zab_PG(xmem, ymem); rozszerzPG(xmem, ymem); } byl = false; for (;;) { auto it = sr_yx.lower_bound(make_pair(y + 1, x - 1)); if (it == sr_yx.end() || it->first > y + 1) break; if (!byl) { byl = true; // biore pierwszego (skrajnie lewego) ymem = it->first; xmem = it->second; } sr_xy.erase(make_pair(it->second, it->first)); sr_yx.erase(it); } if (byl) { dodaj_zab_PG(xmem, ymem); rozszerzPG(xmem, ymem); } } int main() { scanf("%d%d%d", &XS, &YS, &K); int mod = 0; ++XS; // faktyczne pole: od 1 do XS - 1, dodatkowe pola: 0, XS ++YS; zebyLD.emplace(0, 0); zebyPG.emplace(0, 0); zebyLD.emplace(XS, YS); zebyPG.emplace(XS, YS); REP(a, K) { int x, y, zm; scanf("%d%d%d", &x, &y, &zm); x = (x ^ mod) % (XS - 1) + 1; y = (y ^ mod) % (YS - 1) + 1; bool ld = czyLD(x - 1, y + 1), pg = czyPG(x + 1, y - 1); if (ld && pg) { printf("TAK\n"); mod ^= zm; } else { printf("NIE\n"); if (!czyLD(x, y) && !czyPG(x, y)) { sr_xy.emplace(x, y); sr_yx.emplace(y, x); if (ld) rozszerzLD(x - 1, y + 1); if (pg) rozszerzPG(x + 1, y - 1); } } DEBUG( fprintf(stderr, "zęby LD:"); for (auto p : zebyLD) fprintf(stderr, " (%d,%d)", p.first, p.second); fprintf(stderr, "\nzęby PG:"); for (auto p : zebyPG) fprintf(stderr, " (%d,%d)", XS - p.first, YS - p.second); fprintf(stderr, "\n"); ) } } |