#include <cstdio> #include <cmath> #include <algorithm> const int MAXN = 50005; int t,n,w,pow2,posX[MAXN],height[MAXN],finalPosX[MAXN], origOrderRev[MAXN], origOrder[MAXN],finalOrder[MAXN],tree[4*MAXN]; void init(); bool origComp(int,int); bool finalComp(int,int); void createTree(); int getMax(int,int); void clearPos(int); int main() { scanf("%d", &t); while(t--) { int x1,x2,y1,y2; scanf("%d%d", &n, &w); init(); for(int i = 0; i < n; ++i) { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); posX[i] = std::min(x1,x2); height[i] = std::abs(y2-y1); } for(int i = 0; i < n; ++i) { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); finalPosX[i] = std::min(x1,x2); } std::sort(origOrder,origOrder+n,origComp); std::sort(finalOrder,finalOrder+n,finalComp); for(int i = 0; i < n; ++i) origOrderRev[origOrder[i]] = i; createTree(); bool answer = true; for(int i = 0; i < n; ++i) { clearPos(origOrderRev[finalOrder[i]]); if(getMax(0, origOrderRev[finalOrder[i]]) > w - height[finalOrder[i]]) { answer = false; break; } } printf("%s\n", answer ? "TAK" : "NIE"); } } void init() { for(int i = 1; i <= 4*n; ++i) tree[i] = 0; for(int i = 0; i <= n; ++i) origOrder[i] = finalOrder[i] = i; } bool origComp(int a, int b) { return posX[a] < posX[b]; } bool finalComp(int a, int b) { return finalPosX[a] < finalPosX[b]; } void createTree() { pow2 = 1; while(pow2 < n) pow2 *= 2; for(int i = 0; i < n; ++i) tree[pow2+i] = height[origOrder[i]]; for(int i = pow2-1; i > 0; --i) tree[i] = std::max(tree[i*2],tree[i*2+1]); } int getMax(int a, int b) { int left = a+pow2, right = b+pow2, result = 0; while(left < right) { if(left % 2 == 1) { result = std::max(result,tree[left]); left = left/2 + 1; } else left /= 2; if(right % 2 == 0) { result = std::max(result,tree[right]); right = right/2 - 1; } else right /= 2; } if(left == right) result = std::max(result,tree[left]); return result; } void clearPos(int pos) { int p = pow2+pos; tree[p] = 0; p /= 2; while(p > 0) { tree[p] = std::max(tree[2*p],tree[2*p+1]); p /= 2; } }
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 | #include <cstdio> #include <cmath> #include <algorithm> const int MAXN = 50005; int t,n,w,pow2,posX[MAXN],height[MAXN],finalPosX[MAXN], origOrderRev[MAXN], origOrder[MAXN],finalOrder[MAXN],tree[4*MAXN]; void init(); bool origComp(int,int); bool finalComp(int,int); void createTree(); int getMax(int,int); void clearPos(int); int main() { scanf("%d", &t); while(t--) { int x1,x2,y1,y2; scanf("%d%d", &n, &w); init(); for(int i = 0; i < n; ++i) { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); posX[i] = std::min(x1,x2); height[i] = std::abs(y2-y1); } for(int i = 0; i < n; ++i) { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); finalPosX[i] = std::min(x1,x2); } std::sort(origOrder,origOrder+n,origComp); std::sort(finalOrder,finalOrder+n,finalComp); for(int i = 0; i < n; ++i) origOrderRev[origOrder[i]] = i; createTree(); bool answer = true; for(int i = 0; i < n; ++i) { clearPos(origOrderRev[finalOrder[i]]); if(getMax(0, origOrderRev[finalOrder[i]]) > w - height[finalOrder[i]]) { answer = false; break; } } printf("%s\n", answer ? "TAK" : "NIE"); } } void init() { for(int i = 1; i <= 4*n; ++i) tree[i] = 0; for(int i = 0; i <= n; ++i) origOrder[i] = finalOrder[i] = i; } bool origComp(int a, int b) { return posX[a] < posX[b]; } bool finalComp(int a, int b) { return finalPosX[a] < finalPosX[b]; } void createTree() { pow2 = 1; while(pow2 < n) pow2 *= 2; for(int i = 0; i < n; ++i) tree[pow2+i] = height[origOrder[i]]; for(int i = pow2-1; i > 0; --i) tree[i] = std::max(tree[i*2],tree[i*2+1]); } int getMax(int a, int b) { int left = a+pow2, right = b+pow2, result = 0; while(left < right) { if(left % 2 == 1) { result = std::max(result,tree[left]); left = left/2 + 1; } else left /= 2; if(right % 2 == 0) { result = std::max(result,tree[right]); right = right/2 - 1; } else right /= 2; } if(left == right) result = std::max(result,tree[left]); return result; } void clearPos(int pos) { int p = pow2+pos; tree[p] = 0; p /= 2; while(p > 0) { tree[p] = std::max(tree[2*p],tree[2*p+1]); p /= 2; } } |