#include <cstdio> #include <algorithm> #include <queue> #include <vector> using namespace std; const int MAXT = 131072; const int MAXN = 50007; pair <pair <int, int>, int> before[3 * MAXN], after[3 * MAXN]; int tree[MAXT], position[3 * MAXN]; int t, M; void clear(int tab_l, int tree_l) { for (int i = 0; i < tab_l; ++i) { position[i] = 0; before[i].first.first = before[i].first.second = before[i].second = 0; after[i].first.first = after[i].first.second = after[i].second = 0; } for (int i = 1; i < 2 * tree_l; ++i) { tree[i] = 0; } } int query(int a, int b) { a += M; b += M; int result = tree[a]; if (a != b) result = max(tree[b], result); while (a / 2 != b / 2) { if (a % 2 == 0) { result = max(result, tree[a + 1]); } if (b % 2 == 1) { result = max(result, tree[b - 1]); } a /= 2; b /= 2; } return result; } void solve(int n, int h) { for (int i = 0; i < n; ++i) { int x1, x2, y1, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); before[i].first.first = min(x1, x2); before[i].first.second = y1 - y2; if (before[i].first.second < 0) before[i].first.second = -before[i].first.second; before[i].second = i; } sort(before,before+n); for (int i = 0; i < n; ++i) { position[before[i].second] = i; } for (int i = 0; i < n; ++i) { int x1, x2, y1, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); after[i].first.first = min(x1, x2); after[i].first.second = y1 - y2; if (after[i].first.second < 0) after[i].first.second = -after[i].first.second; after[i].second = i; } sort(after,after+n); M = 1; while (M < n) { M *= 2; } for (int i = M; i < 2 * M; ++i) { tree[i] = before[i - M].first.second; } for (int i = M - 1; i >= 1; --i) { tree[i] = max(tree[2 * i], tree[2 * i + 1]); } bool possible = true; for (int i = 0; i < n; ++i) { int a = position[after[i].second]; if (a > i) { if (query (0, a - 1) + after[i].first.second > h) { possible = false; break; } } int place = M + a; tree[place] = 0; while (place != 1) { place /= 2; tree[place] = max(tree[2 * place], tree[2 * place + 1]); } } clear(n, M); if (possible) printf("TAK\n"); else printf("NIE\n"); } int main() { scanf("%d", &t); for (int counter = 0; counter < t; ++counter) { int amount, w; scanf("%d %d", &amount, &w); solve(amount, w); } 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 115 116 117 118 119 120 121 122 | #include <cstdio> #include <algorithm> #include <queue> #include <vector> using namespace std; const int MAXT = 131072; const int MAXN = 50007; pair <pair <int, int>, int> before[3 * MAXN], after[3 * MAXN]; int tree[MAXT], position[3 * MAXN]; int t, M; void clear(int tab_l, int tree_l) { for (int i = 0; i < tab_l; ++i) { position[i] = 0; before[i].first.first = before[i].first.second = before[i].second = 0; after[i].first.first = after[i].first.second = after[i].second = 0; } for (int i = 1; i < 2 * tree_l; ++i) { tree[i] = 0; } } int query(int a, int b) { a += M; b += M; int result = tree[a]; if (a != b) result = max(tree[b], result); while (a / 2 != b / 2) { if (a % 2 == 0) { result = max(result, tree[a + 1]); } if (b % 2 == 1) { result = max(result, tree[b - 1]); } a /= 2; b /= 2; } return result; } void solve(int n, int h) { for (int i = 0; i < n; ++i) { int x1, x2, y1, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); before[i].first.first = min(x1, x2); before[i].first.second = y1 - y2; if (before[i].first.second < 0) before[i].first.second = -before[i].first.second; before[i].second = i; } sort(before,before+n); for (int i = 0; i < n; ++i) { position[before[i].second] = i; } for (int i = 0; i < n; ++i) { int x1, x2, y1, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); after[i].first.first = min(x1, x2); after[i].first.second = y1 - y2; if (after[i].first.second < 0) after[i].first.second = -after[i].first.second; after[i].second = i; } sort(after,after+n); M = 1; while (M < n) { M *= 2; } for (int i = M; i < 2 * M; ++i) { tree[i] = before[i - M].first.second; } for (int i = M - 1; i >= 1; --i) { tree[i] = max(tree[2 * i], tree[2 * i + 1]); } bool possible = true; for (int i = 0; i < n; ++i) { int a = position[after[i].second]; if (a > i) { if (query (0, a - 1) + after[i].first.second > h) { possible = false; break; } } int place = M + a; tree[place] = 0; while (place != 1) { place /= 2; tree[place] = max(tree[2 * place], tree[2 * place + 1]); } } clear(n, M); if (possible) printf("TAK\n"); else printf("NIE\n"); } int main() { scanf("%d", &t); for (int counter = 0; counter < t; ++counter) { int amount, w; scanf("%d %d", &amount, &w); solve(amount, w); } return 0; } |