#include<algorithm>
#include<iostream>
struct Rectangle
{
unsigned x, h, p;
Rectangle(unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned p): x(std::min(x1, x2)), h(std::max(y1, y2) - std::min(y1, y2)), p(p) {}
bool operator<(const Rectangle &r) const
{
return x < r.x;
}
};
bool can_do(unsigned n, unsigned w, const std::vector<Rectangle> &begin, const std::vector<Rectangle> &end)
{
std::vector<unsigned> mapping(n);
{
std::vector<Rectangle>::const_iterator it;
unsigned i;
for(it = begin.cbegin(), i = 0; i < n; ++it, ++i)
mapping[it->p] = i;
}
unsigned size = 1;
while(size < n)
size *= 2;
std::vector<unsigned> tree(2 * size);
for(unsigned i = 0; i < n; ++i)
tree[size + i] = begin[i].h;
for(unsigned i = size - 1; i != 0; --i)
tree[i] = std::max(tree[2 * i], tree[2 * i + 1]);
for(const Rectangle &r: end)
{
unsigned oldpos = mapping[r.p];
unsigned max = 0;
unsigned p = size;
unsigned q = size + oldpos - 1;
while(p < q)
{
if(p % 2 == 1)
max = std::max(max, tree[p++]);
if(q % 2 == 0)
max = std::max(max, tree[q--]);
p /= 2;
q /= 2;
}
if(p == q)
max = std::max(max, tree[p]);
tree[size + oldpos] = 0;
for(unsigned i = (size + oldpos) / 2; i != 0; i /= 2)
tree[i] = std::max(tree[2 * i], tree[2 * i + 1]);
if(max + r.h > w)
return false;
}
return true;
}
int main()
{
std::ios_base::sync_with_stdio(false);
unsigned t;
std::cin >> t;
while(t--)
{
unsigned n, w;
std::cin >> n >> w;
std::vector<Rectangle> begin;
std::vector<Rectangle> end;
begin.reserve(n);
for(unsigned i = 0; i < n; ++i)
{
unsigned x1, y1, x2, y2;
std::cin >> x1 >> y1 >> x2 >> y2;
begin.emplace_back(x1, y1, x2, y2, i);
}
end.reserve(n);
for(unsigned i = 0; i < n; ++i)
{
unsigned x1, y1, x2, y2;
std::cin >> x1 >> y1 >> x2 >> y2;
end.emplace_back(x1, y1, x2, y2, i);
}
std::sort(begin.begin(), begin.end());
std::sort(end.begin(), end.end());
if(can_do(n, w, begin, end))
std::cout << "TAK" << std::endl;
else
std::cout << "NIE" << std::endl;
}
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 | #include<algorithm> #include<iostream> struct Rectangle { unsigned x, h, p; Rectangle(unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned p): x(std::min(x1, x2)), h(std::max(y1, y2) - std::min(y1, y2)), p(p) {} bool operator<(const Rectangle &r) const { return x < r.x; } }; bool can_do(unsigned n, unsigned w, const std::vector<Rectangle> &begin, const std::vector<Rectangle> &end) { std::vector<unsigned> mapping(n); { std::vector<Rectangle>::const_iterator it; unsigned i; for(it = begin.cbegin(), i = 0; i < n; ++it, ++i) mapping[it->p] = i; } unsigned size = 1; while(size < n) size *= 2; std::vector<unsigned> tree(2 * size); for(unsigned i = 0; i < n; ++i) tree[size + i] = begin[i].h; for(unsigned i = size - 1; i != 0; --i) tree[i] = std::max(tree[2 * i], tree[2 * i + 1]); for(const Rectangle &r: end) { unsigned oldpos = mapping[r.p]; unsigned max = 0; unsigned p = size; unsigned q = size + oldpos - 1; while(p < q) { if(p % 2 == 1) max = std::max(max, tree[p++]); if(q % 2 == 0) max = std::max(max, tree[q--]); p /= 2; q /= 2; } if(p == q) max = std::max(max, tree[p]); tree[size + oldpos] = 0; for(unsigned i = (size + oldpos) / 2; i != 0; i /= 2) tree[i] = std::max(tree[2 * i], tree[2 * i + 1]); if(max + r.h > w) return false; } return true; } int main() { std::ios_base::sync_with_stdio(false); unsigned t; std::cin >> t; while(t--) { unsigned n, w; std::cin >> n >> w; std::vector<Rectangle> begin; std::vector<Rectangle> end; begin.reserve(n); for(unsigned i = 0; i < n; ++i) { unsigned x1, y1, x2, y2; std::cin >> x1 >> y1 >> x2 >> y2; begin.emplace_back(x1, y1, x2, y2, i); } end.reserve(n); for(unsigned i = 0; i < n; ++i) { unsigned x1, y1, x2, y2; std::cin >> x1 >> y1 >> x2 >> y2; end.emplace_back(x1, y1, x2, y2, i); } std::sort(begin.begin(), begin.end()); std::sort(end.begin(), end.end()); if(can_do(n, w, begin, end)) std::cout << "TAK" << std::endl; else std::cout << "NIE" << std::endl; } return 0; } |
English