#include <iostream>
#include <algorithm>
#include <memory.h>
#define REP(x,n) for(int x=0;x<(n);++x)
using namespace std;
struct CCar {
int left;
int top;
int right;
int bottom;
int number;
void inline match() {
if (left>right)
swap(left, right);
if (top>bottom)
swap(top, bottom);
}
};
int w,t,n;
const int MAX_N = 50001;
CCar auta[MAX_N];
int afterOrder[MAX_N];
int beforeOrder[MAX_N];
struct Interval_Tree {
int w[MAX_N*4];
int i;
void init(int n) {
i=1;
while(n>i)
i<<=1;
for(int x=0;x<i+i;++x)
w[x]=0;
}
void insert(int a, int val) {
a+=i;
w[a] = val;
while(a!=1) {
a>>=1;
w[a] = max(w[a+a], w[a+a+1]);
}
}
int query(int a, int b) {
if (a>b)
swap(a,b);
a+=i;
b+=i;
int ret=max(w[a], w[b]);
while((a>>1)!=(b>>1)) {
if (~a&1)
ret = max(ret, w[a+1]);
if (b&1)
ret = max(ret, w[b-1]);
a>>=1;
b>>=1;
}
return ret;
}
} drzewo;
bool comp(const CCar& e, const CCar& f) {
return e.left==f.left ? e.top<f.top : e.left < f.left;
}
bool zestaw() {
cin>>n>>w;
drzewo.init(n);
int maks1=0, maks2=0;
REP(x,n) {
auta[x].number=x;
cin>>auta[x].left>>auta[x].top>>auta[x].right>>auta[x].bottom;
auta[x].match();
if (maks2<(auta[x].bottom-auta[x].top)) {
maks2=auta[x].bottom-auta[x].top;
if (maks2>maks1)
swap(maks1, maks2);
}
}
sort(auta, auta+n, comp);
REP(x,n)
beforeOrder[auta[x].number] = x; /// auto #x siedzi teraz na pozycji beforeOrder[x]
REP(x,n) {
auta[x].number=beforeOrder[x];
cin>>auta[x].left>>auta[x].top>>auta[x].right>>auta[x].bottom;
auta[x].match();
}
if (maks1+maks2 <= w) /// każde auta się miną
return true;
sort(auta, auta+n, comp);
REP(x,n)
afterOrder[auta[x].number] = x; /// auto X (po przestawieniu) jest w tablicy auta pod numerem afterOrder[x]
REP(x,n) {
if (drzewo.query(afterOrder[x],n) + (auta[afterOrder[x]].bottom-auta[afterOrder[x]].top) > w)
return false;
drzewo.insert(afterOrder[x], (auta[afterOrder[x]].bottom-auta[afterOrder[x]].top));
}
return true;
}
int main() {
ios_base::sync_with_stdio(0);
cin>>t;
REP(x,t)
cout << (zestaw() ? "TAK" : "NIE") << 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 | #include <iostream> #include <algorithm> #include <memory.h> #define REP(x,n) for(int x=0;x<(n);++x) using namespace std; struct CCar { int left; int top; int right; int bottom; int number; void inline match() { if (left>right) swap(left, right); if (top>bottom) swap(top, bottom); } }; int w,t,n; const int MAX_N = 50001; CCar auta[MAX_N]; int afterOrder[MAX_N]; int beforeOrder[MAX_N]; struct Interval_Tree { int w[MAX_N*4]; int i; void init(int n) { i=1; while(n>i) i<<=1; for(int x=0;x<i+i;++x) w[x]=0; } void insert(int a, int val) { a+=i; w[a] = val; while(a!=1) { a>>=1; w[a] = max(w[a+a], w[a+a+1]); } } int query(int a, int b) { if (a>b) swap(a,b); a+=i; b+=i; int ret=max(w[a], w[b]); while((a>>1)!=(b>>1)) { if (~a&1) ret = max(ret, w[a+1]); if (b&1) ret = max(ret, w[b-1]); a>>=1; b>>=1; } return ret; } } drzewo; bool comp(const CCar& e, const CCar& f) { return e.left==f.left ? e.top<f.top : e.left < f.left; } bool zestaw() { cin>>n>>w; drzewo.init(n); int maks1=0, maks2=0; REP(x,n) { auta[x].number=x; cin>>auta[x].left>>auta[x].top>>auta[x].right>>auta[x].bottom; auta[x].match(); if (maks2<(auta[x].bottom-auta[x].top)) { maks2=auta[x].bottom-auta[x].top; if (maks2>maks1) swap(maks1, maks2); } } sort(auta, auta+n, comp); REP(x,n) beforeOrder[auta[x].number] = x; /// auto #x siedzi teraz na pozycji beforeOrder[x] REP(x,n) { auta[x].number=beforeOrder[x]; cin>>auta[x].left>>auta[x].top>>auta[x].right>>auta[x].bottom; auta[x].match(); } if (maks1+maks2 <= w) /// każde auta się miną return true; sort(auta, auta+n, comp); REP(x,n) afterOrder[auta[x].number] = x; /// auto X (po przestawieniu) jest w tablicy auta pod numerem afterOrder[x] REP(x,n) { if (drzewo.query(afterOrder[x],n) + (auta[afterOrder[x]].bottom-auta[afterOrder[x]].top) > w) return false; drzewo.insert(afterOrder[x], (auta[afterOrder[x]].bottom-auta[afterOrder[x]].top)); } return true; } int main() { ios_base::sync_with_stdio(0); cin>>t; REP(x,t) cout << (zestaw() ? "TAK" : "NIE") << endl; return 0; } |
English