#include <algorithm>
#include <cstdio>
#include <tuple>
//#include <iterator>
using namespace std;
typedef tuple<unsigned, unsigned> samochod; //x, h, nr
typedef tuple<unsigned, unsigned, unsigned, unsigned> wspolrzedne;
bool sprawdz(vector<samochod>, const vector<unsigned>, const unsigned);
int main() {
unsigned t;
scanf("%u", &t);
for(unsigned i = 0; i < t; ++i) {
unsigned n,w;
scanf("%u%u", &n, &w);
vector<wspolrzedne> pobrane(n);
for(auto& x : pobrane)
scanf("%u%u%u%u", &get<0>(x), &get<1>(x), &get<2>(x), &get<3>(x));
vector<samochod> poczatkowa; poczatkowa.reserve(n);
transform(begin(pobrane), end(pobrane), back_inserter(poczatkowa),
[](wspolrzedne x) {return make_tuple(min(get<0>(x),get<2>(x)),
max(get<1>(x), get<3>(x)) - min(get<1>(x),get<3>(x)));});
for(auto& x : pobrane)
scanf("%u%u%u%u", &get<0>(x), &get<1>(x), &get<2>(x), &get<3>(x));
vector<unsigned> koncowa; koncowa.reserve(n);
transform(begin(pobrane), end(pobrane), back_inserter(koncowa),
[](wspolrzedne x) {return min(get<0>(x), get<2>(x));});
pobrane.clear(); pobrane.shrink_to_fit();
const bool poprawnie = sprawdz(move(poczatkowa), move(koncowa), w);
printf("%s\n", poprawnie ? "TAK" : "NIE");
}
}
class drzewo_przedzialowe {
vector<unsigned> wierzcholki;
inline unsigned ojciec(unsigned x) {
return x / 2;
}
inline unsigned lewy_syn(unsigned x) {
return 2 * x;
}
inline unsigned prawy_syn(unsigned x) {
return 2 * x + 1;
}
public:
template<typename T>
drzewo_przedzialowe(const T p, const T q) {
const unsigned n = distance(p,q);
unsigned dl = 1;
while(dl < n)
dl <<= 1;
wierzcholki.resize(dl * 2, 0);
for_each(p, q, [&](decltype(*p) x){wierzcholki[dl+get<0>(x)] = get<1>(x);});
for(unsigned i = dl-1; i > 0; --i) {
wierzcholki[i] = max(wierzcholki[lewy_syn(i)], wierzcholki[prawy_syn(i)]);
}
}
void update(unsigned i) {
i += wierzcholki.size()/2;
wierzcholki[i] = 0;
i = ojciec(i);
while(i != 0) {
wierzcholki[i] = max(wierzcholki[lewy_syn(i)], wierzcholki[prawy_syn(i)]);
i = ojciec(i);
}
}
unsigned query(unsigned i, unsigned j) {
if(j == 0)
return 0;
unsigned va = wierzcholki.size()/2 + i, vb = va-i+j - 1;
unsigned wynik = max(wierzcholki[va], wierzcholki[vb]);
while(ojciec(va) != ojciec(vb)) {
if(va % 2 == 0)
wynik = max(wynik, wierzcholki[va + 1]);
if(vb % 2 == 1)
wynik = max(wynik, wierzcholki[vb - 1]);
va = ojciec(va);
vb = ojciec(vb);
}
return wynik;
}
};
bool sprawdz(vector<samochod> samochody_poczatek, const vector<unsigned> samochody_koniec, const unsigned w) {
vector<unsigned> poczatkowa; poczatkowa.reserve(samochody_poczatek.size());//kolejnosc
unsigned iij = 0U;
generate_n(back_inserter(poczatkowa), samochody_poczatek.size(),
[&](void){return iij++;});
vector<unsigned> koncowa(poczatkowa);
sort(begin(poczatkowa), end(poczatkowa), [&](unsigned i, unsigned j){return get<0>(samochody_poczatek[i]) < get<0>(samochody_poczatek[j]);});
//return true;
sort(begin(koncowa), end(koncowa), [&](unsigned i, unsigned j){return samochody_koniec[i] < samochody_koniec[j];});
for(unsigned i = 0U; i < samochody_poczatek.size(); ++i)
get<0>(samochody_poczatek[poczatkowa[i]]) = i;
//return true;
drzewo_przedzialowe najwiekszy(begin(samochody_poczatek), end(samochody_poczatek));
for(auto rozpatrywany : koncowa) {
unsigned h_max = najwiekszy.query(0U, get<0>(samochody_poczatek[rozpatrywany]));
if(h_max > w - get<1>(samochody_poczatek[rozpatrywany]))
return false;
najwiekszy.update(get<0>(samochody_poczatek[rozpatrywany]));
}
return true;
}
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 | #include <algorithm> #include <cstdio> #include <tuple> //#include <iterator> using namespace std; typedef tuple<unsigned, unsigned> samochod; //x, h, nr typedef tuple<unsigned, unsigned, unsigned, unsigned> wspolrzedne; bool sprawdz(vector<samochod>, const vector<unsigned>, const unsigned); int main() { unsigned t; scanf("%u", &t); for(unsigned i = 0; i < t; ++i) { unsigned n,w; scanf("%u%u", &n, &w); vector<wspolrzedne> pobrane(n); for(auto& x : pobrane) scanf("%u%u%u%u", &get<0>(x), &get<1>(x), &get<2>(x), &get<3>(x)); vector<samochod> poczatkowa; poczatkowa.reserve(n); transform(begin(pobrane), end(pobrane), back_inserter(poczatkowa), [](wspolrzedne x) {return make_tuple(min(get<0>(x),get<2>(x)), max(get<1>(x), get<3>(x)) - min(get<1>(x),get<3>(x)));}); for(auto& x : pobrane) scanf("%u%u%u%u", &get<0>(x), &get<1>(x), &get<2>(x), &get<3>(x)); vector<unsigned> koncowa; koncowa.reserve(n); transform(begin(pobrane), end(pobrane), back_inserter(koncowa), [](wspolrzedne x) {return min(get<0>(x), get<2>(x));}); pobrane.clear(); pobrane.shrink_to_fit(); const bool poprawnie = sprawdz(move(poczatkowa), move(koncowa), w); printf("%s\n", poprawnie ? "TAK" : "NIE"); } } class drzewo_przedzialowe { vector<unsigned> wierzcholki; inline unsigned ojciec(unsigned x) { return x / 2; } inline unsigned lewy_syn(unsigned x) { return 2 * x; } inline unsigned prawy_syn(unsigned x) { return 2 * x + 1; } public: template<typename T> drzewo_przedzialowe(const T p, const T q) { const unsigned n = distance(p,q); unsigned dl = 1; while(dl < n) dl <<= 1; wierzcholki.resize(dl * 2, 0); for_each(p, q, [&](decltype(*p) x){wierzcholki[dl+get<0>(x)] = get<1>(x);}); for(unsigned i = dl-1; i > 0; --i) { wierzcholki[i] = max(wierzcholki[lewy_syn(i)], wierzcholki[prawy_syn(i)]); } } void update(unsigned i) { i += wierzcholki.size()/2; wierzcholki[i] = 0; i = ojciec(i); while(i != 0) { wierzcholki[i] = max(wierzcholki[lewy_syn(i)], wierzcholki[prawy_syn(i)]); i = ojciec(i); } } unsigned query(unsigned i, unsigned j) { if(j == 0) return 0; unsigned va = wierzcholki.size()/2 + i, vb = va-i+j - 1; unsigned wynik = max(wierzcholki[va], wierzcholki[vb]); while(ojciec(va) != ojciec(vb)) { if(va % 2 == 0) wynik = max(wynik, wierzcholki[va + 1]); if(vb % 2 == 1) wynik = max(wynik, wierzcholki[vb - 1]); va = ojciec(va); vb = ojciec(vb); } return wynik; } }; bool sprawdz(vector<samochod> samochody_poczatek, const vector<unsigned> samochody_koniec, const unsigned w) { vector<unsigned> poczatkowa; poczatkowa.reserve(samochody_poczatek.size());//kolejnosc unsigned iij = 0U; generate_n(back_inserter(poczatkowa), samochody_poczatek.size(), [&](void){return iij++;}); vector<unsigned> koncowa(poczatkowa); sort(begin(poczatkowa), end(poczatkowa), [&](unsigned i, unsigned j){return get<0>(samochody_poczatek[i]) < get<0>(samochody_poczatek[j]);}); //return true; sort(begin(koncowa), end(koncowa), [&](unsigned i, unsigned j){return samochody_koniec[i] < samochody_koniec[j];}); for(unsigned i = 0U; i < samochody_poczatek.size(); ++i) get<0>(samochody_poczatek[poczatkowa[i]]) = i; //return true; drzewo_przedzialowe najwiekszy(begin(samochody_poczatek), end(samochody_poczatek)); for(auto rozpatrywany : koncowa) { unsigned h_max = najwiekszy.query(0U, get<0>(samochody_poczatek[rozpatrywany])); if(h_max > w - get<1>(samochody_poczatek[rozpatrywany])) return false; najwiekszy.update(get<0>(samochody_poczatek[rozpatrywany])); } return true; } |
English