#include <cassert>
#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
#define all(a) begin(a), end(a)
constexpr ll MOD = 1e9 + 7;
struct T {
ll k, b;
ll eval(ll x) const { return (k * x + b) % MOD; }
T substitute(T const &x) const { return {k * x.k % MOD, (k * x.b + b) % MOD}; }
};
struct Tree {
vector<T> tree;
void build(int i, int l, int r, vector<T> const &a) {
if (l == r) {
tree[i] = a[l];
return;
}
int m = (l + r) / 2;
build(2 * i, l, m, a);
build(2 * i + 1, m + 1, r, a);
tree[i] = tree[2 * i + 1].substitute(tree[2 * i]);
}
void init(vector<T> const &a) {
int n = a.size();
tree.resize(4 * n);
build(1, 0, n - 1, a);
}
T get(int i, int l, int r, int lb, int rb) const {
if (rb < l || lb > r) {
return {1, 0};
}
if (lb <= l && r <= rb) {
return tree[i];
}
int m = (l + r) / 2;
return get(2 * i + 1, m + 1, r, lb, rb).substitute(get(2 * i, l, m, lb, rb));
}
};
void solve() {
int n, q;
cin >> n >> q;
vector<pair<ll, ll>> a(n);
for (auto &[k, b] : a) {
cin >> b >> k;
}
vector<T> lin(n);
for (int i = 0; i < n; i++) {
lin[i] = a[i].first > 1 ? T{a[i].first, 0} : T{1, a[i].second};
}
Tree tree;
tree.init(lin);
vector<int> nxt(n + 1, n);
for (int i = n - 1; i >= 0; --i) {
nxt[i] = a[i].first > 1 ? i : nxt[i + 1];
}
vector<ll> pref(n);
for (int i = 0; i < n; i++) {
if (i) {
pref[i] = pref[i - 1];
}
pref[i] += a[i].second;
}
auto gp = [&](int i) { return i < 0 ? 0 : pref[i]; };
while (q--) {
ll val, l, r;
cin >> val >> l >> r;
--r;
while (val < MOD) {
int t = nxt[l];
// cerr << l << " -> " << t << "\n";
if (t > r) {
break;
}
val += gp(t - 1) - gp(l - 1);
l = t;
if (val >= MOD) {
break;
}
val = max(val + a[t].second, a[t].first * val);
l = t + 1;
}
if (val < MOD) {
val += gp(r) - gp(l - 1);
val %= MOD;
cout << val << "\n";
continue;
}
val %= MOD;
cout << tree.get(1, 0, n - 1, l, r).eval(val) << "\n";
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int q = 1;
// cin >> q;
while (q--) {
solve();
}
}
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 115 116 117 118 119 120 121 122 123 124 125 126 | #include <cassert> #include <iostream> #include <vector> using namespace std; using ll = long long; #define all(a) begin(a), end(a) constexpr ll MOD = 1e9 + 7; struct T { ll k, b; ll eval(ll x) const { return (k * x + b) % MOD; } T substitute(T const &x) const { return {k * x.k % MOD, (k * x.b + b) % MOD}; } }; struct Tree { vector<T> tree; void build(int i, int l, int r, vector<T> const &a) { if (l == r) { tree[i] = a[l]; return; } int m = (l + r) / 2; build(2 * i, l, m, a); build(2 * i + 1, m + 1, r, a); tree[i] = tree[2 * i + 1].substitute(tree[2 * i]); } void init(vector<T> const &a) { int n = a.size(); tree.resize(4 * n); build(1, 0, n - 1, a); } T get(int i, int l, int r, int lb, int rb) const { if (rb < l || lb > r) { return {1, 0}; } if (lb <= l && r <= rb) { return tree[i]; } int m = (l + r) / 2; return get(2 * i + 1, m + 1, r, lb, rb).substitute(get(2 * i, l, m, lb, rb)); } }; void solve() { int n, q; cin >> n >> q; vector<pair<ll, ll>> a(n); for (auto &[k, b] : a) { cin >> b >> k; } vector<T> lin(n); for (int i = 0; i < n; i++) { lin[i] = a[i].first > 1 ? T{a[i].first, 0} : T{1, a[i].second}; } Tree tree; tree.init(lin); vector<int> nxt(n + 1, n); for (int i = n - 1; i >= 0; --i) { nxt[i] = a[i].first > 1 ? i : nxt[i + 1]; } vector<ll> pref(n); for (int i = 0; i < n; i++) { if (i) { pref[i] = pref[i - 1]; } pref[i] += a[i].second; } auto gp = [&](int i) { return i < 0 ? 0 : pref[i]; }; while (q--) { ll val, l, r; cin >> val >> l >> r; --r; while (val < MOD) { int t = nxt[l]; // cerr << l << " -> " << t << "\n"; if (t > r) { break; } val += gp(t - 1) - gp(l - 1); l = t; if (val >= MOD) { break; } val = max(val + a[t].second, a[t].first * val); l = t + 1; } if (val < MOD) { val += gp(r) - gp(l - 1); val %= MOD; cout << val << "\n"; continue; } val %= MOD; cout << tree.get(1, 0, n - 1, l, r).eval(val) << "\n"; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int q = 1; // cin >> q; while (q--) { solve(); } } |
English