#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5, M = 1e6 + 5; int n; vector<int> pos; vector<pair<int, int>> a[M];
class Point { public: int x, y, w; } points[N];
class SegmentTree { class Values { public: long long max, add; int index; }; class Node { public: int left, right; Values val; Node() = default; Node(int l, int r) : left(l), right(r), val() {} }; Node tr[M << 2]; static int get_lc(int k) { return k << 1; } static int get_rc(int k) { return k << 1 | 1; } int get_mid(int k) { return (tr[k].left + tr[k].right) >> 1; } void make_lazy_add(int k, long long val) { tr[k].val.add += val; tr[k].val.max += val; } void push_up(int k) { int lc = get_lc(k), rc = get_rc(k); if (tr[lc].val.max > tr[rc].val.max) { tr[k].val.max = tr[lc].val.max; tr[k].val.index = tr[lc].val.index; } else { tr[k].val.max = tr[rc].val.max; tr[k].val.index = tr[rc].val.index; } } void push_down(int k) { if (tr[k].val.add == 0) return void(); int lc = get_lc(k), rc = get_rc(k); make_lazy_add(lc, tr[k].val.add); make_lazy_add(rc, tr[k].val.add); tr[k].val.add = 0; } public: void build_tree(int k, int l, int r) { tr[k] = Node(l, r); if (tr[k].left == tr[k].right) { tr[k].val.max = -pos[l - 1]; tr[k].val.index = l; return void(); } int mid = get_mid(k); int lc = get_lc(k), rc = get_rc(k); build_tree(lc, l, mid); build_tree(rc, mid + 1, r); push_up(k); } void modify(int k, int l, int r, int val) { if (tr[k].left >= l && tr[k].right <= r) { make_lazy_add(k, val); return void(); } push_down(k); int mid = get_mid(k); int lc = get_lc(k), rc = get_rc(k); if (r <= mid) { modify(lc, l, r, val); } else if (l > mid) { modify(rc, l, r, val); } else { modify(lc, l, mid, val); modify(rc, mid + 1, r, val); } push_up(k); } pair<long long, long long> query(int k, int l, int r) { if (tr[k].left >= l && tr[k].right <= r) { return make_pair(tr[k].val.max, tr[k].val.index); } push_down(k); int mid = get_mid(k); int lc = get_lc(k), rc = get_rc(k); if (r <= mid) { return query(lc, l, r); } else if (l > mid) { return query(rc, l, r); } else { return max(query(lc, l, mid), query(rc, mid + 1, r)); } } } seg;
int get_index(int val) { return lower_bound(pos.begin(), pos.end(), val) - pos.begin() + 1; }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n; for (int i = 1; i <= n; i ++) { cin >> points[i].x >> points[i].y >> points[i].w; pos.emplace_back(points[i].x); pos.emplace_back(points[i].y); if (points[i].x > points[i].y) { swap(points[i].x, points[i].y); } } sort(pos.begin(), pos.end()); pos.erase(unique(pos.begin(), pos.end()), pos.end()); int limit = 0; for (int i = 1; i <= n; i ++) { points[i].x = get_index(points[i].x); points[i].y = get_index(points[i].y); limit = max(limit, points[i].y); a[points[i].x].emplace_back(points[i].y, points[i].w); } seg.build_tree(1, 1, limit); long long answer = -1ll << 60, left = 0, right = 0; for (int line = limit; line >= 1; line --) { for (auto p : a[line]) { seg.modify(1, p.first, limit, p.second); } pair<long long, long long> result = seg.query(1, line, limit); result.first += pos[line - 1]; if (result.first > answer) { answer = result.first; left = pos[line - 1]; right = pos[result.second - 1]; } } if (answer < 0) { answer = 0; left = 1e9 + 1, right = 1e9 + 1; } cout << answer << "\n"; cout << left << " " << left << " " << right << " " << right << '\n'; return 0; }
|