#include <bits/stdc++.h>
using ll = long long;
using pll = std::pair<ll, ll>;
const ll MOD = 1'000'000'000 + 7;
const int MODLOG = 40;
ll pow(ll a, ll k) {
ll answer = 1;
while (k) {
if (k & 1) {
answer = (answer * a) % MOD;
}
a = (a * a) % MOD;
k /= 2;
}
return answer;
}
ll inv(ll a) {
return pow(a, MOD - 2);
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, q;
std::cin >> n >> q;
std::vector<pll> ab(n);
std::vector<pll> opSuf(n + 1);
std::vector<pll> nextMul(n);
for (int i = 0; i < n; i++) {
std::cin >> ab[i].first >> ab[i].second;
}
pll nextMulTemp = {n, 0};
for (int i = n - 1; i >= 0; i--) {
nextMul[i] = nextMulTemp;
if (ab[i].second >= 2) {
nextMulTemp = {i, 0};
} else {
nextMulTemp.second += ab[i].first;
}
}
opSuf[n] = {0, 1};
for (int i = n - 1; i >= 0; i--) {
if (ab[i].second == 1) {
opSuf[i] = {
(opSuf[i + 1].first + opSuf[i + 1].second * ab[i].first) % MOD,
opSuf[i + 1].second,
};
} else {
opSuf[i] = {
opSuf[i + 1].first,
(opSuf[i + 1].second * ab[i].second) % MOD,
};
}
}
auto solve = [&](ll x, int l, int r) -> ll {
bool laped = false;
int idx = l;
for (int i = 0; i < MODLOG && idx < r; i++) {
{
if (!laped && x + ab[idx].first > x * ab[idx].second) {
x += ab[idx].first;
} else {
x *= ab[idx].second;
}
if (x >= MOD) {
laped = true;
}
x %= MOD;
}
{
if (nextMul[idx].first > r) {
x = (x + nextMul[idx].second - nextMul[r - 1].second + MOD) % MOD;
return x;
} else {
x = x + nextMul[idx].second;
idx = nextMul[idx].first;
if (x >= MOD) {
laped = true;
}
x %= MOD;
}
}
}
ll opSufRS_C = inv(opSuf[r].second);
pll mulFirst = {
(opSuf[idx].first - opSuf[r].first) * opSufRS_C,
opSuf[idx].second * opSufRS_C
};
mulFirst = {
(((mulFirst.first % MOD) + MOD) % MOD),
(((mulFirst.second % MOD) + MOD) % MOD)
};
x = (x * mulFirst.second) % MOD;
x = (x + mulFirst.first) % MOD;
return x;
};
while (q--) {
ll x;
int l, r;
std::cin >> x >> l >> r;
std::cout << solve(x, l, r) << "\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 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 | #include <bits/stdc++.h> using ll = long long; using pll = std::pair<ll, ll>; const ll MOD = 1'000'000'000 + 7; const int MODLOG = 40; ll pow(ll a, ll k) { ll answer = 1; while (k) { if (k & 1) { answer = (answer * a) % MOD; } a = (a * a) % MOD; k /= 2; } return answer; } ll inv(ll a) { return pow(a, MOD - 2); } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int n, q; std::cin >> n >> q; std::vector<pll> ab(n); std::vector<pll> opSuf(n + 1); std::vector<pll> nextMul(n); for (int i = 0; i < n; i++) { std::cin >> ab[i].first >> ab[i].second; } pll nextMulTemp = {n, 0}; for (int i = n - 1; i >= 0; i--) { nextMul[i] = nextMulTemp; if (ab[i].second >= 2) { nextMulTemp = {i, 0}; } else { nextMulTemp.second += ab[i].first; } } opSuf[n] = {0, 1}; for (int i = n - 1; i >= 0; i--) { if (ab[i].second == 1) { opSuf[i] = { (opSuf[i + 1].first + opSuf[i + 1].second * ab[i].first) % MOD, opSuf[i + 1].second, }; } else { opSuf[i] = { opSuf[i + 1].first, (opSuf[i + 1].second * ab[i].second) % MOD, }; } } auto solve = [&](ll x, int l, int r) -> ll { bool laped = false; int idx = l; for (int i = 0; i < MODLOG && idx < r; i++) { { if (!laped && x + ab[idx].first > x * ab[idx].second) { x += ab[idx].first; } else { x *= ab[idx].second; } if (x >= MOD) { laped = true; } x %= MOD; } { if (nextMul[idx].first > r) { x = (x + nextMul[idx].second - nextMul[r - 1].second + MOD) % MOD; return x; } else { x = x + nextMul[idx].second; idx = nextMul[idx].first; if (x >= MOD) { laped = true; } x %= MOD; } } } ll opSufRS_C = inv(opSuf[r].second); pll mulFirst = { (opSuf[idx].first - opSuf[r].first) * opSufRS_C, opSuf[idx].second * opSufRS_C }; mulFirst = { (((mulFirst.first % MOD) + MOD) % MOD), (((mulFirst.second % MOD) + MOD) % MOD) }; x = (x * mulFirst.second) % MOD; x = (x + mulFirst.first) % MOD; return x; }; while (q--) { ll x; int l, r; std::cin >> x >> l >> r; std::cout << solve(x, l, r) << "\n"; } } |
English