#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500005;
const long long MOD = 1000000000LL + 7;
long long a[MAXN], b[MAXN];
int n, q;
struct Affine {
long long A, B;
};
Affine compose(const Affine& f, const Affine& g) {
return { f.A * g.A % MOD, (f.B * g.A % MOD + g.B) % MOD };
}
Affine seg_mult[4 * MAXN];
Affine seg_add[4 * MAXN];
// next_mult[i] = first position p >= i where b[p] != 1, or n+1 if none
int next_mult[MAXN];
void build_next_mult() {
next_mult[n + 1] = n + 1;
for (int i = n; i >= 1; i--)
next_mult[i] = (b[i] != 1) ? i : next_mult[i + 1];
}
void build(int v, int l, int r) {
if (l == r) {
seg_mult[v] = (b[l] != 1) ? Affine{b[l], 0} : Affine{1, a[l]};
seg_add[v] = Affine{1, a[l]};
return;
}
int mid = (l + r) / 2;
build(2*v, l, mid);
build(2*v+1, mid+1, r);
seg_mult[v] = compose(seg_mult[2*v], seg_mult[2*v+1]);
seg_add[v] = compose(seg_add[2*v], seg_add[2*v+1]);
}
Affine query(Affine* seg, int v, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return seg[v];
int mid = (l + r) / 2;
if (qr <= mid) return query(seg, 2*v, l, mid, ql, qr);
if (ql > mid) return query(seg, 2*v+1, mid+1, r, ql, qr);
return compose(
query(seg, 2*v, l, mid, ql, qr),
query(seg, 2*v+1, mid+1, r, ql, qr)
);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> q;
for (int i = 1; i <= n; i++)
cin >> a[i] >> b[i];
build_next_mult();
build(1, 1, n);
while (q--) {
long long x;
int l, r, p;
cin >> x >> l >> r;
for (p = l+1; p<=r; ++p) {
if (b[p] == 1) {
int nm = std::min(next_mult[p]-1, r);
x += query(seg_add, 1, 1, n, p, nm).B;
p = nm;
} else {
x = std::max(x * b[p], x + a[p]);
}
if (x > MOD) break;
}
if (p < r) {
auto val = query(seg_mult, 1, 1, n, p+1, r);
x = ((x % MOD) * val.A + val.B) % MOD;
}
cout << (x % MOD) << "\n";
}
return 0;
}
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 | #include <bits/stdc++.h> using namespace std; const int MAXN = 500005; const long long MOD = 1000000000LL + 7; long long a[MAXN], b[MAXN]; int n, q; struct Affine { long long A, B; }; Affine compose(const Affine& f, const Affine& g) { return { f.A * g.A % MOD, (f.B * g.A % MOD + g.B) % MOD }; } Affine seg_mult[4 * MAXN]; Affine seg_add[4 * MAXN]; // next_mult[i] = first position p >= i where b[p] != 1, or n+1 if none int next_mult[MAXN]; void build_next_mult() { next_mult[n + 1] = n + 1; for (int i = n; i >= 1; i--) next_mult[i] = (b[i] != 1) ? i : next_mult[i + 1]; } void build(int v, int l, int r) { if (l == r) { seg_mult[v] = (b[l] != 1) ? Affine{b[l], 0} : Affine{1, a[l]}; seg_add[v] = Affine{1, a[l]}; return; } int mid = (l + r) / 2; build(2*v, l, mid); build(2*v+1, mid+1, r); seg_mult[v] = compose(seg_mult[2*v], seg_mult[2*v+1]); seg_add[v] = compose(seg_add[2*v], seg_add[2*v+1]); } Affine query(Affine* seg, int v, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) return seg[v]; int mid = (l + r) / 2; if (qr <= mid) return query(seg, 2*v, l, mid, ql, qr); if (ql > mid) return query(seg, 2*v+1, mid+1, r, ql, qr); return compose( query(seg, 2*v, l, mid, ql, qr), query(seg, 2*v+1, mid+1, r, ql, qr) ); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> q; for (int i = 1; i <= n; i++) cin >> a[i] >> b[i]; build_next_mult(); build(1, 1, n); while (q--) { long long x; int l, r, p; cin >> x >> l >> r; for (p = l+1; p<=r; ++p) { if (b[p] == 1) { int nm = std::min(next_mult[p]-1, r); x += query(seg_add, 1, 1, n, p, nm).B; p = nm; } else { x = std::max(x * b[p], x + a[p]); } if (x > MOD) break; } if (p < r) { auto val = query(seg_mult, 1, 1, n, p+1, r); x = ((x % MOD) * val.A + val.B) % MOD; } cout << (x % MOD) << "\n"; } return 0; } |
English