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 108 109 110 111 112 113 114
| #include <bits/stdc++.h> using namespace std;
const int MAX = 1e5 + 5; struct Node { int l, r, t, ok; bool operator < (const Node& rhs) const { if (l != rhs.l) return l < rhs.l; if (r != rhs.r) return r < rhs.r; if (t != rhs.t) return t < rhs.t; return ok < rhs.ok; } }; struct TreeNode { int l, r; long long sum; } tree[MAX * 70]; int rootM[MAX], rootR[MAX], idx; int si[MAX], mi[MAX], ri[MAX], n, q; set<Node> st;
void modify(int l, int r, int pre, int& now, int x, int y) { now = ++idx; tree[now] = tree[pre]; tree[now].sum += y; if (l == r) return; int mid = (l + r) >> 1; if (x <= mid) modify(l, mid, tree[pre].l, tree[now].l, x, y); else modify(mid + 1, r, tree[pre].r, tree[now].r, x, y); }
long long query(int l, int r, int L, int R, int ql, int qr) { if (l > qr || r < ql) return 0; if (ql <= l && r <= qr) { return tree[R].sum - tree[L].sum; } int mid = (l + r) >> 1; return query(l, mid, tree[L].l, tree[R].l, ql, qr) + query(mid + 1, r, tree[L].r, tree[R].r, ql, qr); }
long long query(Node node, int now) { int l = node.l, r = node.r, last = node.t, ok = node.ok; int x = now - last; long long ans = 0; if (ok) { ans = query(0, 100000, rootM[l - 1], rootM[r], 1, x) + query(0, 100000, rootR[l - 1], rootR[r], x + 1, 100000) * x; } else { for (int i = l; i <= r; i++) { ans += min((long long) mi[i], (long long) si[i] + (long long) ri[i] * x); } } return ans; }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n; for (int i = 1; i <= n; i++) { cin >> si[i] >> mi[i] >> ri[i]; modify(0, 100000, rootM[i - 1], rootM[i], ri[i] ? ((mi[i] + ri[i] - 1) / ri[i]) : 0, ri[i] ? mi[i] : 0); modify(0, 100000, rootR[i - 1], rootR[i], ri[i] ? ((mi[i] + ri[i] - 1) / ri[i]) : 0, ri[i]); } st.insert({1, n, 0, 0}); cin >> q; while (q--) { int t, l, r; cin >> t >> l >> r; auto lptr = --st.upper_bound({l, INT_MAX, 0, 0}); auto rptr = --st.upper_bound({r, INT_MAX, 0, 0}); long long ans = 0; if (lptr == rptr) { int L = lptr->l, R = lptr->r, T = lptr->t, ok = lptr->ok; st.erase(lptr); ans += query({max(l, L), min(r, R), T, ok}, t); if (l > L) { st.insert({L, l - 1, T, ok}); } if (r < R) { st.insert({r + 1, R, T, ok}); } st.insert({l, r, t, 1}); } else { set<Node>::iterator it = st.end(), temp = lptr; for (auto ptr = ++temp; ptr != rptr; ptr++) { if (it != st.end()) { st.erase(it); it = st.end(); } ans += query({ptr->l, ptr->r, ptr->t, ptr->ok}, t); it = ptr; } if (it != st.end()) { st.erase(it); it = st.end(); } ans += query({l, lptr->r, lptr->t, lptr->ok}, t); ans += query({rptr->l, r, rptr->t, rptr->ok}, t); if (l > lptr->l) { st.insert({lptr->l, l - 1, lptr->t, lptr->ok}); } if (r < rptr->r) { st.insert({r + 1, rptr->r, rptr->t, rptr->ok}); } st.erase(lptr); st.erase(rptr); st.insert({l, r, t, 1}); } cout << ans << "\n"; } return 0; }
|