#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n, m, k, r, c, z, x;
const LL M = 10000000;
struct xxx{
LL ojciec;
int ranga;
};
map<LL, xxx> t;
set<int> s[100009];
set<int> ::iterator it;
void MakeSet(LL x){
t[x].ojciec=x;
}
LL Find(LL x){
if(t[x].ojciec == x)
return t[x].ojciec;
t[x].ojciec=Find(t[x].ojciec);
return t[x].ojciec;
}
void Union(LL a, LL b){
LL fa=Find(a);
LL fb=Find(b);
if(fa==fb)return;
if(t[fa].ranga>t[fb].ranga ){
t[fb].ojciec=t[fa].ojciec;
t[fa].ranga++;
}
else{
t[fa].ojciec=t[fb].ojciec;
t[fb].ranga++;
}
}
bool check(){
r = (r^x)%n;
c = (c^x)%m;
LL tmp = M*r + c;
MakeSet(tmp);
LL gorne = -3;
LL dolne = -4;
if(r == 0 || c == m-1){
gorne = -1;
}
else{
if(!s[r-1].empty()){
it = s[r-1].lower_bound(c+1);
if(*it > c+1 && it != s[r-1].begin() ){
--it;
gorne = *it + (r-1)*M;
}
if(*it <= c+1)
gorne = *it + (r-1)*M;
if(it == s[r-1].end())
gorne = *s[r-1].rbegin() + (r-1)*M;
}
}
if(r==n-1 || c == 0){
dolne = -2;
}
else{
if(!s[r+1].empty()){
it = s[r+1].lower_bound(c-1);
if(*it >= c-1)
dolne = *it + (r+1)*M;
if(it == s[r+1].end())
dolne = -4;
}
}
if(Find(gorne) == Find(-1) && Find(dolne) == Find(-2)){
x = x^z;
return true;
}
if(gorne != -3){
Union(gorne, tmp);
}
if(dolne != -4){
Union(dolne, tmp);
}
s[r].insert(c);
return false;
}
int main(){
scanf("%d%d%d", &n, &m, &k);
MakeSet(-1);
MakeSet(-2);
MakeSet(-3);
MakeSet(-4);
for(int i=0; i<k; i++){
scanf("%d%d%d", &r, &c, &z);
if(check())
puts("TAK");
else
puts("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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #include <bits/stdc++.h> using namespace std; typedef long long LL; int n, m, k, r, c, z, x; const LL M = 10000000; struct xxx{ LL ojciec; int ranga; }; map<LL, xxx> t; set<int> s[100009]; set<int> ::iterator it; void MakeSet(LL x){ t[x].ojciec=x; } LL Find(LL x){ if(t[x].ojciec == x) return t[x].ojciec; t[x].ojciec=Find(t[x].ojciec); return t[x].ojciec; } void Union(LL a, LL b){ LL fa=Find(a); LL fb=Find(b); if(fa==fb)return; if(t[fa].ranga>t[fb].ranga ){ t[fb].ojciec=t[fa].ojciec; t[fa].ranga++; } else{ t[fa].ojciec=t[fb].ojciec; t[fb].ranga++; } } bool check(){ r = (r^x)%n; c = (c^x)%m; LL tmp = M*r + c; MakeSet(tmp); LL gorne = -3; LL dolne = -4; if(r == 0 || c == m-1){ gorne = -1; } else{ if(!s[r-1].empty()){ it = s[r-1].lower_bound(c+1); if(*it > c+1 && it != s[r-1].begin() ){ --it; gorne = *it + (r-1)*M; } if(*it <= c+1) gorne = *it + (r-1)*M; if(it == s[r-1].end()) gorne = *s[r-1].rbegin() + (r-1)*M; } } if(r==n-1 || c == 0){ dolne = -2; } else{ if(!s[r+1].empty()){ it = s[r+1].lower_bound(c-1); if(*it >= c-1) dolne = *it + (r+1)*M; if(it == s[r+1].end()) dolne = -4; } } if(Find(gorne) == Find(-1) && Find(dolne) == Find(-2)){ x = x^z; return true; } if(gorne != -3){ Union(gorne, tmp); } if(dolne != -4){ Union(dolne, tmp); } s[r].insert(c); return false; } int main(){ scanf("%d%d%d", &n, &m, &k); MakeSet(-1); MakeSet(-2); MakeSet(-3); MakeSet(-4); for(int i=0; i<k; i++){ scanf("%d%d%d", &r, &c, &z); if(check()) puts("TAK"); else puts("NIE"); } return 0; } |
polski