#include <iostream> #include <algorithm> struct Car { unsigned int startingPosition; unsigned int finalPosition; unsigned int size; }; struct CarPosition { unsigned int id; unsigned int x1; unsigned int y1; unsigned int x2; unsigned int y2; }; struct ComparePosition { bool operator()(const CarPosition& first, const CarPosition& second) { return first.x1 < second.x1; }; } compare; CarPosition startingPosition[50000]; CarPosition finalPosition[50000]; Car car[50000]; unsigned int maxima[140000] = {0}; unsigned int getMaximum(unsigned int powerOfTwo, unsigned int end) { unsigned int result = 0; unsigned int binary[16] = {0}; unsigned int i = end; unsigned int j = 0; while (i>0) { binary[j++] = i%2; i /= 2; } unsigned int actualPower = 1; for (unsigned int k=0; k<16; ++k) { if (binary[k]==1) { result = std::max(result, maxima[powerOfTwo/actualPower + end/actualPower]); end -= actualPower; } actualPower *=2; } return result; } void updateHeap(unsigned int leafStart, unsigned int index, unsigned int height) { maxima[leafStart+index] = 0; unsigned int i = leafStart + index; while (i>1) { if ((i-1)%2 == 0) { maxima[(i-1)/2+1] = std::max(maxima[i], maxima[i+1]); } else { maxima[(i-1)/2+1] = std::max(maxima[i-1], maxima[i]); } i = (i-1)/2+1; } } int main() { bool result = true; unsigned int tests; std::cin >> tests; for (unsigned int i=0; i<tests; ++i) { unsigned int cars; std::cin >> cars; unsigned int height; std::cin >> height; for (unsigned int j=0; j<cars; ++j) { startingPosition[j].id = j; unsigned int x1, x2, y1, y2; std::cin >> x1; std::cin >> y1; std::cin >> x2; std::cin >> y2; startingPosition[j].x1 = std::min(x1, x2); startingPosition[j].y1 = std::min(y1, y2); startingPosition[j].x2 = std::max(x1, x2); startingPosition[j].y2 = std::max(y1, y2); car[j].size = startingPosition[j].y2 - startingPosition[j].y1; } for (unsigned int j=0; j<cars; ++j) { finalPosition[j].id = j; unsigned int x1, x2, y1, y2; std::cin >> x1; std::cin >> y1; std::cin >> x2; std::cin >> y2; finalPosition[j].x1 = std::min(x1, x2); finalPosition[j].y1 = std::min(y1, y2); finalPosition[j].x2 = std::max(x1, x2); finalPosition[j].y2 = std::max(y1, y2); } std::sort(startingPosition, startingPosition+cars, compare); std::sort(finalPosition, finalPosition+cars, compare); for (unsigned int j=0; j<cars; ++j) { car[startingPosition[j].id].startingPosition = j; car[finalPosition[j].id].finalPosition = j; } unsigned int powerOfTwo = 1; while (powerOfTwo < cars) powerOfTwo *=2; unsigned int j; for (j=1; j<=cars; ++j) maxima[powerOfTwo+j] = car[startingPosition[j-1].id].size; for (j=cars+1; j<=powerOfTwo; ++j) maxima[powerOfTwo+j] = 0; unsigned int index = powerOfTwo/2; while (index > 0) { for (unsigned int k=1; k<=index; ++k) { maxima[index+k] = std::max(maxima[2*(index+k)-1], maxima[2*(index+k)]); } index /= 2; } for (unsigned int k=0; k<cars; ++k) { unsigned int startingPosition = car[finalPosition[k].id].startingPosition+1; unsigned int size = car[finalPosition[k].id].size; if (startingPosition>1) result = (size + getMaximum(powerOfTwo, startingPosition-1) <= height); if (!result) break; updateHeap(powerOfTwo, startingPosition, height); } std::cout << (result ? "TAK" : "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 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 | #include <iostream> #include <algorithm> struct Car { unsigned int startingPosition; unsigned int finalPosition; unsigned int size; }; struct CarPosition { unsigned int id; unsigned int x1; unsigned int y1; unsigned int x2; unsigned int y2; }; struct ComparePosition { bool operator()(const CarPosition& first, const CarPosition& second) { return first.x1 < second.x1; }; } compare; CarPosition startingPosition[50000]; CarPosition finalPosition[50000]; Car car[50000]; unsigned int maxima[140000] = {0}; unsigned int getMaximum(unsigned int powerOfTwo, unsigned int end) { unsigned int result = 0; unsigned int binary[16] = {0}; unsigned int i = end; unsigned int j = 0; while (i>0) { binary[j++] = i%2; i /= 2; } unsigned int actualPower = 1; for (unsigned int k=0; k<16; ++k) { if (binary[k]==1) { result = std::max(result, maxima[powerOfTwo/actualPower + end/actualPower]); end -= actualPower; } actualPower *=2; } return result; } void updateHeap(unsigned int leafStart, unsigned int index, unsigned int height) { maxima[leafStart+index] = 0; unsigned int i = leafStart + index; while (i>1) { if ((i-1)%2 == 0) { maxima[(i-1)/2+1] = std::max(maxima[i], maxima[i+1]); } else { maxima[(i-1)/2+1] = std::max(maxima[i-1], maxima[i]); } i = (i-1)/2+1; } } int main() { bool result = true; unsigned int tests; std::cin >> tests; for (unsigned int i=0; i<tests; ++i) { unsigned int cars; std::cin >> cars; unsigned int height; std::cin >> height; for (unsigned int j=0; j<cars; ++j) { startingPosition[j].id = j; unsigned int x1, x2, y1, y2; std::cin >> x1; std::cin >> y1; std::cin >> x2; std::cin >> y2; startingPosition[j].x1 = std::min(x1, x2); startingPosition[j].y1 = std::min(y1, y2); startingPosition[j].x2 = std::max(x1, x2); startingPosition[j].y2 = std::max(y1, y2); car[j].size = startingPosition[j].y2 - startingPosition[j].y1; } for (unsigned int j=0; j<cars; ++j) { finalPosition[j].id = j; unsigned int x1, x2, y1, y2; std::cin >> x1; std::cin >> y1; std::cin >> x2; std::cin >> y2; finalPosition[j].x1 = std::min(x1, x2); finalPosition[j].y1 = std::min(y1, y2); finalPosition[j].x2 = std::max(x1, x2); finalPosition[j].y2 = std::max(y1, y2); } std::sort(startingPosition, startingPosition+cars, compare); std::sort(finalPosition, finalPosition+cars, compare); for (unsigned int j=0; j<cars; ++j) { car[startingPosition[j].id].startingPosition = j; car[finalPosition[j].id].finalPosition = j; } unsigned int powerOfTwo = 1; while (powerOfTwo < cars) powerOfTwo *=2; unsigned int j; for (j=1; j<=cars; ++j) maxima[powerOfTwo+j] = car[startingPosition[j-1].id].size; for (j=cars+1; j<=powerOfTwo; ++j) maxima[powerOfTwo+j] = 0; unsigned int index = powerOfTwo/2; while (index > 0) { for (unsigned int k=1; k<=index; ++k) { maxima[index+k] = std::max(maxima[2*(index+k)-1], maxima[2*(index+k)]); } index /= 2; } for (unsigned int k=0; k<cars; ++k) { unsigned int startingPosition = car[finalPosition[k].id].startingPosition+1; unsigned int size = car[finalPosition[k].id].size; if (startingPosition>1) result = (size + getMaximum(powerOfTwo, startingPosition-1) <= height); if (!result) break; updateHeap(powerOfTwo, startingPosition, height); } std::cout << (result ? "TAK" : "NIE") << std::endl; } return 0; } |