#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
template<typename T>
struct segtree {
int n;
vector<T> value;
segtree(vector<T> leaves): n(leaves.size()), value(2*n) {
copy(begin(leaves), end(leaves), begin(value)+n);
for (int i = n-1; i >= 1; i--) {
value[i] = value[2*i] + value[2*i+1];
}
}
void update(int i, T v) {
i += n;
value[i] = v;
for (i /= 2; i; i /= 2) {
value[i] = value[2*i] + value[2*i+1];
}
}
T query(int i, int j) {
i += n, j += n;
T resl, resr;
for (; i < j; i /= 2, j /= 2) {
if (i & 1) resl = resl + value[i++];
if (j & 1) resr = value[--j] + resr;
}
return resl + resr;
}
};
const int MOD = 1e9 + 7;
struct node {
i64 u = 1, v = 0;
node operator+(const node &n) const {
return {u*n.u % MOD, (v*n.u + n.v) % MOD};
}
i64 operator()(i64 x) {
return (u*x + v) % MOD;
}
};
int main() {
int n, q;
cin >> n >> q;
vector<i64> a(n), b(n);
for (int i = 0; i < n; i++) cin >> a[i] >> b[i];
vector<i64> asum(n+1);
for (int i = 0; i < n; i++) {
asum[i+1] = asum[i] + a[i];
}
vector<int> next_mul(n+1, n);
for (int i = n-1; i >= 0; i--) {
next_mul[i] = next_mul[i+1];
if (b[i] > 1) next_mul[i] = i;
}
vector<node> leaves;
for (int i = 0; i < n; i++) {
leaves.push_back(b[i] > 1 ? node{b[i], 0} : node{1, a[i]});
}
segtree<node> S(leaves);
while (q--) {
i64 x;
int l, r;
cin >> x >> l >> r;
while (l < r) {
if (l < next_mul[l]) {
int i = min(r, next_mul[l]);
x += asum[i] - asum[l];
l = i;
} else if (x < MOD) {
x = max(x+a[l], x*b[l]);
l++;
} else {
x = S.query(l, r)(x % MOD);
l = r;
}
}
cout << x%MOD << '\n';
}
}
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 | #include <bits/stdc++.h> using namespace std; using i64 = long long; template<typename T> struct segtree { int n; vector<T> value; segtree(vector<T> leaves): n(leaves.size()), value(2*n) { copy(begin(leaves), end(leaves), begin(value)+n); for (int i = n-1; i >= 1; i--) { value[i] = value[2*i] + value[2*i+1]; } } void update(int i, T v) { i += n; value[i] = v; for (i /= 2; i; i /= 2) { value[i] = value[2*i] + value[2*i+1]; } } T query(int i, int j) { i += n, j += n; T resl, resr; for (; i < j; i /= 2, j /= 2) { if (i & 1) resl = resl + value[i++]; if (j & 1) resr = value[--j] + resr; } return resl + resr; } }; const int MOD = 1e9 + 7; struct node { i64 u = 1, v = 0; node operator+(const node &n) const { return {u*n.u % MOD, (v*n.u + n.v) % MOD}; } i64 operator()(i64 x) { return (u*x + v) % MOD; } }; int main() { int n, q; cin >> n >> q; vector<i64> a(n), b(n); for (int i = 0; i < n; i++) cin >> a[i] >> b[i]; vector<i64> asum(n+1); for (int i = 0; i < n; i++) { asum[i+1] = asum[i] + a[i]; } vector<int> next_mul(n+1, n); for (int i = n-1; i >= 0; i--) { next_mul[i] = next_mul[i+1]; if (b[i] > 1) next_mul[i] = i; } vector<node> leaves; for (int i = 0; i < n; i++) { leaves.push_back(b[i] > 1 ? node{b[i], 0} : node{1, a[i]}); } segtree<node> S(leaves); while (q--) { i64 x; int l, r; cin >> x >> l >> r; while (l < r) { if (l < next_mul[l]) { int i = min(r, next_mul[l]); x += asum[i] - asum[l]; l = i; } else if (x < MOD) { x = max(x+a[l], x*b[l]); l++; } else { x = S.query(l, r)(x % MOD); l = r; } } cout << x%MOD << '\n'; } } |
English