#include #include #include #include #include "optimization.h" using namespace std; using ll = long long; template struct Monoid; template struct ValidMonoid : private Mon { using value_type = typename Mon::value_type; using T = typename Mon::value_type; static_assert(std::is_same_v(), std::declval())), T>); static_assert(std::is_same_v); using Mon::compose; using Mon::identity; }; template struct Updater : Updater> { using valid = ValidMonoid>; }; template struct ValidUpdater : private Upd { using value_type = typename Upd::value_type; using update_type = typename Upd::update_type; using T = typename Upd::value_type; using U = typename Upd::update_type; using valid = ValidMonoid; static_assert(std::is_same_v(), std::declval(), std::declval(), std::declval())), T>); using Upd::update; using Upd::compose; using Upd::identity; }; template struct Updater> : Monoid { using M = Monoid; using valid = ValidMonoid; using value_type = typename M::value_type; using update_type = typename M::value_type; static value_type update(const value_type& a, const update_type& b, size_t l, size_t r) { return M::compose(a, b); } }; template struct STOp { using composer = ValidMonoid>; using updater = ValidUpdater>; }; template struct ValidSTOp : Op { using compose_valid = ValidMonoid; using updater_valid = ValidUpdater; static_assert(std::is_same_v); using typename Op::composer; using typename Op::updater; }; template class SegmentTreeFromAbove { public: using Op = ValidSTOp>; using Cm = ValidMonoid; using Up = ValidUpdater; using T = typename Cm::value_type; using U = typename Up::update_type; explicit SegmentTreeFromAbove(size_t n) : n(n) { data.resize(4 * n, Cm::identity()); updates.resize(data.size(), Up::identity()); } explicit SegmentTreeFromAbove(int n) : SegmentTreeFromAbove(static_cast(n)) {} template explicit SegmentTreeFromAbove(const Cont& cont) : SegmentTreeFromAbove(cont.size()) { build(cont); } T compute(size_t l, size_t r) { return compute(1, 0, n, l, r); } void applyToLeaf(size_t i, std::function f) { applyToLeaf(1, 0, n, i, std::move(f)); } void applyToLeaf(size_t i, std::function f) { applyToLeaf(i, [f](const T& t, size_t l, size_t r){ return f(t); }); } void set(size_t i, T x) { applyToLeaf(i, [&x](const T& y, size_t l, size_t r) { return x; }); } void update(size_t i, U upd) { applyToLeaf(i, [this, &upd](const T& x, size_t l, size_t r) { return Up::update(x, upd, l, r); }); } void update(size_t l, size_t r, U upd) { update(1, 0, n, l, r, upd); } private: T compute(size_t v, size_t vl, size_t vr, size_t l, size_t r) { if (disjoint(vl, vr, l, r)) return Cm::identity(); if (embedded(vl, vr, l, r)) return data[v]; size_t vm = mid(vl, vr); return Up::update( Cm::compose( compute(left(v), vl, vm, l, r), compute(right(v), vm, vr, l, r) ), updates[v], vl, vr ); } void update(size_t v, size_t vl, size_t vr, size_t l, size_t r, U upd) { recompute(v, vl, vr); if (disjoint(vl, vr, l, r)) return; if (embedded(vl, vr, l, r)) { updates[v] = Up::compose(updates[v], upd); recompute(v, vl, vr); return; } size_t vm = mid(vl, vr); push(v); update(left(v), vl, vm, l, r, upd); update(right(v), vm, vr, l, r, upd); recompute(v, vl, vr); } void push(size_t v) { updates[left(v)] = Up::compose(updates[left(v)], updates[v]); updates[right(v)] = Up::compose(updates[right(v)], updates[v]); updates[v] = Up::identity(); } void applyToLeaf(size_t v, size_t vl, size_t vr, size_t i, std::function f) { if (vl == i && vr == i + 1) { data[v] = Up::update(f(data[v], vl, vr), updates[i], vl, vr); return; } size_t vm = mid(vl, vr); if (i < vm) applyToLeaf(left(v), vl, vm, i, f); else applyToLeaf(right(v), vm, vr, i, f); recompute(v, vl, vr); } template void build(const Cont& cnt) { size_t i = 0; for (auto x : cnt) { set(i++, x); } } bool disjoint(size_t vl, size_t vr, size_t l, size_t r) { return vr <= l || r <= vl; } bool embedded(size_t vl, size_t vr, size_t l, size_t r) { return l <= vl && vr <= r; } size_t mid(size_t vl, size_t vr) { return (vl + vr + 1) / 2; } size_t left(size_t i) { return 2 * i; } size_t right(size_t i) { return 2 * i + 1; } void recompute(size_t i, size_t vl, size_t vr) { if(vl + 1 == vr) { data[i] = Up::update(data[i], updates[i], vl, vr); updates[i] = Up::identity(); } else { data[i] = Up::update( Cm::compose(data[left(i)], data[right(i)]), updates[i], vl, vr ); } } size_t n; std::vector data; std::vector updates; }; template struct Sum { }; template struct Monoid> { using value_type = T; static T identity() { return id; }; static T compose(T a, T b) { return a + b; } }; template struct Updater> : Monoid> { using update_type = T; static T update(T x, T up, size_t l, size_t r) { return x + up * (r - l); } }; template::max()> struct Min { }; template struct Monoid> { using value_type = T; static T identity() { return id; }; static T compose(T a, T b) { return min(a, b); } }; template::min()> struct Max { }; template struct Monoid> { using value_type = T; static T identity() { return *id; }; static T compose(T a, T b) { return max(a, b); } }; //template //struct Updater> : Monoid> { // // using value_type = T; // using update_type = T; // // static value_type update(value_type a, update_type b, size_t l, size_t r) { // return max(a, b); // } // //}; template struct PureSum { }; template struct Updater> : Monoid> { using update_type = T; static T update(const T& a, const T& b, size_t l, size_t r) { return a + b; } }; struct CountSegments {}; struct CSNode { enum class Color { BLACK, WHITE }; Color beg, end; size_t black_cnt, len; }; std::string to_str(CSNode::Color c) { return c == CSNode::Color::BLACK ? "B" : "W"; } bool debug = false; template<> struct Monoid { using value_type = CSNode; using Color = CSNode::Color; static value_type identity() { return {Color::WHITE, Color::WHITE, 0, 0}; } static value_type compose(value_type a, value_type b) { CSNode res = {a.beg, b.end, a.black_cnt + b.black_cnt - (a.end == Color::BLACK && b.beg == Color::BLACK), a.len + b.len}; if(debug) std::cerr << "Composing " << to_str(a.beg) << "[" << a.black_cnt << "]" << to_str(a.end) << " with " << to_str(b.beg) << "[" << b.black_cnt << "]" << to_str(b.end) << " result " << to_str(res.beg) << "[" << res.black_cnt << "]" << to_str(res.end) << std::endl; return res; } }; template<> struct Updater { using value_type = CSNode; using update_type = std::optional; static update_type identity() { return std::optional(); } static update_type compose(update_type a, update_type b) { if(!b.has_value()) return a; return b; } static value_type update(value_type a, update_type u, size_t l, size_t r) { if(!u.has_value()) return a; CSNode res = {u.value(), u.value(), u.value() == CSNode::Color::BLACK, u.value() == CSNode::Color::BLACK ? (r - l) : 0}; if(debug) std::cerr << "Updating " << to_str(a.beg) << "[" << a.black_cnt << "]" << to_str(a.end) << " to " << to_str(res.beg) << "[" << res.black_cnt << "]" << to_str(res.end) << std::endl; return res; } }; struct RectUpdater; template<> struct Updater : Monoid> { using value_type = pair; using update_type = int; static value_type update(value_type rect, update_type k, size_t l, size_t r) { return {rect.first + k, rect.second}; } }; constexpr pair identity{0, -1}; template struct ComplexOp { }; template struct STOp> { using composer = ValidMonoid::composer>; using updater = ValidUpdater::updater>; }; int main() { int n = readInt(); std::vector> events; for (int i = 0; i < n; ++i) { int x1 = readInt(), y1 = readInt(), x2 = readInt(), y2 = readInt(), k = readInt(); events.emplace_back(x1, 0, y1, y2, k, i); events.emplace_back(x2, 2, y1, y2, k, i); } int K = 2e5; sort(events.begin(), events.end()); std::vector> rects(n); int N = 2 * K + 2; SegmentTreeFromAbove, &identity>> tree(N); for(auto [x, type, y1, y2, k, i] : events) { y1 += K; y2 += K + 1; switch(type) { case 0: { rects[i] = tree.compute(y2, N); rects[i].first += k; break; } case 2: { tree.update(y1, y2, pair{rects[i].first, i}); break; } } } int maxI = 0; for (int i = 0; i < n; ++i) { if(rects[i].first > rects[maxI].first) { maxI = i; } } std::vector chain; for(int i = maxI; i != -1; i = rects[i].second) { chain.push_back(i); } std::reverse(chain.begin(), chain.end()); writeInt(rects[maxI].first, '\n'); for(int i : chain) { writeInt(i + 1, ' '); } writeChar('\n'); } // x1 y1 x2 y2 // a1 b1 a2 b2 // a1 > x2 && b2 < y1 //WWWWWWWWWWW //WWWWWWWWWWW //WWBBWWWWWWW //WWBBBBWWWWW //WWBBBBWWWWW //WWBBBBWBBWW //WWBWBBWBBWW //WWWWWWWWWWW //int main() { // int n = readInt(); // int N = 1000002; // SegmentTreeFromAbove tree(N); // for (int i = 0; i < n; ++i) { // debug = i == 5; // int color = readChar(), x = readInt(), l = readInt(); // x += 500000; // tree.update(x, x+l, color == 'W' ? CSNode::Color::WHITE : CSNode::Color::BLACK); // CSNode ans = tree.compute(0, N); // writeInt(ans.black_cnt, ' '); // writeInt(ans.len, '\n'); // } //} //int main() { // int n = readInt(), q = readInt(); // vector v; // v.reserve(n); // for (int i = 0; i < n; ++i) { // v.push_back(readInt()); // } // SegmentTreeFromAbove(-1e15)>, PureSum>> tree(v); // for (int i = 0; i < q; ++i) { // int cmd = readChar(); // readChar(); // readChar(); // int l = readInt() - 1, r = readInt(); // if (cmd == 'm') { // writeInt(tree.compute(l, r), '\n'); // } else { // int x = readInt(); // tree.update(l, r, x); // } // } // return 0; //}