#include <iostream>
#include <set>
#include <vector>
#include <stack>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
unsigned long long int n, m, k, r, c, z;
unsigned long long int x = 0;
unsigned long long int a, b, coord;
cin >> n >> m >> k;
set<unsigned long long> strongholds;
set<unsigned long long> visited;
set<unsigned long long> path;
stack<unsigned long long> path_stack;
unsigned long long max_coord = n * m;
unsigned long long path_length = n + m - 1;
unsigned long long curr;
for (int i = 0; i < k; ++i) {
cin >> r >> c >> z;
a = (r ^ x) % n;
b = (c ^ x) % m;
coord = a + n * b;
auto it = path.find(coord);
if (it != path.end() || path.empty()) {
// new stronghold is on the current path or there is no path
visited.clear();
path.clear();
visited.insert(0);
path_stack.push(0);
while (!path_stack.empty()) {
curr = path_stack.top();
visited.insert(curr);
if ( // try right
(curr + n) < max_coord // not on the bottom edge
&& curr + n != coord // not hitting new stronghold
&& (strongholds.find(curr + n)) == strongholds.end() // not hitting existing stronghold
&& (visited.find(curr + n)) == visited.end() // not already visited
) {
path_stack.push(curr + n);
} else if ( // try down
(curr + 1) % n != 0 // not on the bottom edge
&& curr + 1 != coord // not hitting new stronghold
&& (strongholds.find(curr + 1)) == strongholds.end() // not hitting existing stronghold
&& (visited.find(curr + 1)) == visited.end() // not already visited
) {
path_stack.push(curr + 1);
} else {
// there is no move
if (curr == max_coord - 1) {
while (!path_stack.empty()){
curr = path_stack.top();
path_stack.pop();
path.insert(curr);
}
} else {
path_stack.pop();
}
}
}
if (path.size() != path_length) {
// there is no path because of the new stronghold
x = x ^ z;
visited.clear();
path.clear();
cout << "TAK" << "\n";
} else {
// there is a path around new stronghold, add it to the list
strongholds.insert(coord);
cout << "NIE" << "\n";
}
} else {
//stronghold is not on the current path, it can be safely added
strongholds.insert(coord);
cout << "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 | #include <iostream> #include <set> #include <vector> #include <stack> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); unsigned long long int n, m, k, r, c, z; unsigned long long int x = 0; unsigned long long int a, b, coord; cin >> n >> m >> k; set<unsigned long long> strongholds; set<unsigned long long> visited; set<unsigned long long> path; stack<unsigned long long> path_stack; unsigned long long max_coord = n * m; unsigned long long path_length = n + m - 1; unsigned long long curr; for (int i = 0; i < k; ++i) { cin >> r >> c >> z; a = (r ^ x) % n; b = (c ^ x) % m; coord = a + n * b; auto it = path.find(coord); if (it != path.end() || path.empty()) { // new stronghold is on the current path or there is no path visited.clear(); path.clear(); visited.insert(0); path_stack.push(0); while (!path_stack.empty()) { curr = path_stack.top(); visited.insert(curr); if ( // try right (curr + n) < max_coord // not on the bottom edge && curr + n != coord // not hitting new stronghold && (strongholds.find(curr + n)) == strongholds.end() // not hitting existing stronghold && (visited.find(curr + n)) == visited.end() // not already visited ) { path_stack.push(curr + n); } else if ( // try down (curr + 1) % n != 0 // not on the bottom edge && curr + 1 != coord // not hitting new stronghold && (strongholds.find(curr + 1)) == strongholds.end() // not hitting existing stronghold && (visited.find(curr + 1)) == visited.end() // not already visited ) { path_stack.push(curr + 1); } else { // there is no move if (curr == max_coord - 1) { while (!path_stack.empty()){ curr = path_stack.top(); path_stack.pop(); path.insert(curr); } } else { path_stack.pop(); } } } if (path.size() != path_length) { // there is no path because of the new stronghold x = x ^ z; visited.clear(); path.clear(); cout << "TAK" << "\n"; } else { // there is a path around new stronghold, add it to the list strongholds.insert(coord); cout << "NIE" << "\n"; } } else { //stronghold is not on the current path, it can be safely added strongholds.insert(coord); cout << "NIE" << "\n"; } } return 0; } |
English