| 12
 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;
 }
 
 |