#include <cstdio> #include <vector> #include <algorithm> #include <functional> #define REP(i, n) for (int i = 0; i < (n); ++i) #define FOR(i, a, b) for (int i = (a); i <= (b); ++i) #define MP make_pair #define FI first #define SE second #define PII pair<int, int> #define PB push_back #define LL long long using namespace std; struct Rect { int id, left, right, height; Rect(int id, int left, int right, int height) : id(id), left(left), right(right), height(height) { } }; class LeftComp { public: bool operator()(const Rect& a, const Rect& b) const { return a.left < b.left; } }; int n, w; vector<Rect> a; vector<Rect> b; vector<int> posA; int size; vector<int> tree; int parent(int pos) { return (pos - 1)/2; } int leftSon(int pos) { return 2*pos + 1; } int rightSon(int pos) { return 2*pos + 2; } int rightSibling(int pos) { return pos + 1; } int treePos(int i) { return size - 1 + i; } void updateTree(int i, int val) { int pos = treePos(i); tree[pos] = val; while (pos > 0) { pos = parent(pos); tree[pos] = max(tree[leftSon(pos)], tree[rightSon(pos)]); } } int getMax(int i) { int pos = 0; int pow2 = size; int number = i + 1; int res = tree[size - 1]; while (number > 0) { while (pow2 > number) { pos = leftSon(pos); pow2 /= 2; } res = max(res, tree[pos]); pos = rightSibling(pos); number -= pow2; } return res; } bool canMove(int i) { if (i == 0) return true; return getMax(i - 1) + a[i].height <= w; } void buildTree() { size = 1; while (size < n) size *= 2; tree.clear(); REP(i, 2*size - 1) tree.PB(0); REP(i, n) updateTree(i, a[i].height); } bool solve() { sort(a.begin(), a.end(), LeftComp()); posA.clear(); posA.resize(n); REP(i, n) posA[a[i].id] = i; sort(b.begin(), b.end(), LeftComp()); buildTree(); REP(i, n) { int ai = posA[b[i].id]; if (canMove(ai)) updateTree(ai, 0); else return false; } return true; } int main() { int t; scanf("%d", &t); REP(tt, t) { scanf("%d%d", &n, &w); a.clear(); REP(i, n) { int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); Rect rect(i, min(x1, x2), max(x1, x2), max(y1, y2) - min(y1, y2)); a.PB(rect); } b.clear(); REP(i, n) { int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); Rect rect(i, min(x1, x2), max(x1, x2), max(y1, y2) - min(y1, y2)); b.PB(rect); } printf("%s\n", solve() ? "TAK" : "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 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 163 | #include <cstdio> #include <vector> #include <algorithm> #include <functional> #define REP(i, n) for (int i = 0; i < (n); ++i) #define FOR(i, a, b) for (int i = (a); i <= (b); ++i) #define MP make_pair #define FI first #define SE second #define PII pair<int, int> #define PB push_back #define LL long long using namespace std; struct Rect { int id, left, right, height; Rect(int id, int left, int right, int height) : id(id), left(left), right(right), height(height) { } }; class LeftComp { public: bool operator()(const Rect& a, const Rect& b) const { return a.left < b.left; } }; int n, w; vector<Rect> a; vector<Rect> b; vector<int> posA; int size; vector<int> tree; int parent(int pos) { return (pos - 1)/2; } int leftSon(int pos) { return 2*pos + 1; } int rightSon(int pos) { return 2*pos + 2; } int rightSibling(int pos) { return pos + 1; } int treePos(int i) { return size - 1 + i; } void updateTree(int i, int val) { int pos = treePos(i); tree[pos] = val; while (pos > 0) { pos = parent(pos); tree[pos] = max(tree[leftSon(pos)], tree[rightSon(pos)]); } } int getMax(int i) { int pos = 0; int pow2 = size; int number = i + 1; int res = tree[size - 1]; while (number > 0) { while (pow2 > number) { pos = leftSon(pos); pow2 /= 2; } res = max(res, tree[pos]); pos = rightSibling(pos); number -= pow2; } return res; } bool canMove(int i) { if (i == 0) return true; return getMax(i - 1) + a[i].height <= w; } void buildTree() { size = 1; while (size < n) size *= 2; tree.clear(); REP(i, 2*size - 1) tree.PB(0); REP(i, n) updateTree(i, a[i].height); } bool solve() { sort(a.begin(), a.end(), LeftComp()); posA.clear(); posA.resize(n); REP(i, n) posA[a[i].id] = i; sort(b.begin(), b.end(), LeftComp()); buildTree(); REP(i, n) { int ai = posA[b[i].id]; if (canMove(ai)) updateTree(ai, 0); else return false; } return true; } int main() { int t; scanf("%d", &t); REP(tt, t) { scanf("%d%d", &n, &w); a.clear(); REP(i, n) { int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); Rect rect(i, min(x1, x2), max(x1, x2), max(y1, y2) - min(y1, y2)); a.PB(rect); } b.clear(); REP(i, n) { int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); Rect rect(i, min(x1, x2), max(x1, x2), max(y1, y2) - min(y1, y2)); b.PB(rect); } printf("%s\n", solve() ? "TAK" : "NIE"); } return 0; } |