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
| struct Segment_Tree { struct Node { int l, r, mx; } tr[N << 2]; void pushup(int x) { tr[x].mx = std::max(tr[x << 1].mx, tr[x << 1 | 1].mx); } void build(int x, int l, int r) { tr[x] = {l, r, -1}; if (l == r) return; int mid = (l + r) >> 1; build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r); } void modify(int x, int pos, int c) { chkmax(tr[x].mx, c); if (tr[x].l ^ tr[x].r) modify(pos <= (tr[x].l + tr[x].r) >> 1 ? x << 1 : x << 1 | 1, pos, c); } int query(int x, int l, int r) { if (tr[x].l > r || tr[x].r < l) return -1; if (tr[x].l >= l && tr[x].r <= r) return tr[x].mx; return std::max(query(x << 1, l, r), query(x << 1 | 1, l, r)); } } seg; void solve(int yl, int yr, std::vector<int> rid, std::vector<int> bid) { if (rid.empty() || bid.empty()) return; int mxid = 0, mid = (yl + yr) >> 1; for (int &x : rid) if (r[x].y <= mid && r[x].v > r[mxid].v) mxid = x; if (mxid) for (int &x : bid) if (b[x].y > mid) vd.push_back({mxid, x}); mxid = 0; for (int &x : bid) if (b[x].y > mid && b[x].v > b[mxid].v) mxid = x; if (mxid) for (int &x : rid) if (r[x].y <= mid) vd.push_back({x, mxid}); std::vector<int> r1, r2, b1, b2; for (int &x : rid) if (r[x].y <= mid) r1.push_back(x); else r2.push_back(x); for (int &x : bid) if (b[x].y <= mid) b1.push_back(x); else b2.push_back(x); solve(yl, mid, r1, b1), solve(mid + 1, yr, r2, b2); } int main() { std::cin >> n; for (int i = 1; i <= n; ++ i) scanf("%d %d %d", &r[i].x, &r[i].y, &r[i].v); for (int i = 1; i <= n; ++ i) scanf("%d %d %d", &b[i].x, &b[i].y, &b[i].v); std::cin >> Q; for (int i = 1; i <= Q; ++ i) scanf("%d %d", &q[i].l, &q[i].r), q[i].id = i, q[i].res = -1; std::vector<int> allid(n), ws(n); for (int i = 0; i < n; ++ i) allid[i] = i + 1; solve(1, 1e9, allid, allid); auto loc = [&](int x) { return std::lower_bound(ws.begin(), ws.end(), x) - ws.begin() + 1; }; for (int i = 0; i < n; ++ i) ws[i] = b[i + 1].x; std::sort(ws.begin(), ws.end()); seg.build(1, 1, n); std::sort(vd.begin(), vd.end(), [&](PII &x, PII &y) { return r[x.first].x < r[y.first].x; }); std::sort(q + 1, q + Q + 1, [&](Query &q1, Query &q2) { return q1.l < q2.l; }); int it = 0, ed = vd.size(); for (int i = 1; i <= Q; ++ i) { while (it < ed && r[vd[it].first].x <= q[i].l) seg.modify(1, loc(b[vd[it].second].x), r[vd[it].first].v + b[vd[it].second].v), it ++; chkmax(q[i].res, seg.query(1, loc(q[i].r), n)); } seg.build(1, 1, n); it = vd.size() - 1; for (int i = Q; i; -- i) { while (it >= 0 && r[vd[it].first].x >= q[i].l) seg.modify(1, loc(b[vd[it].second].x), r[vd[it].first].v + b[vd[it].second].v), it --; chkmax(q[i].res, seg.query(1, 1, loc(q[i].r) - 1)); } std::sort(q + 1, q + Q + 1, [&](Query &q1, Query &q2) { return q1.id < q2.id; }); for (int i = 1; i <= Q; ++ i) printf("%d\n", q[i].res); return 0; }
|