#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const long long MOD = 1e9 + 7;
const long long MAX_VAL = 1e9;
struct Func {
long long m, d;
};
struct Wydarznie {
long long a, b;
};
int M;
Func tree[1048576];
vector<Wydarznie> wydarz;
vector<long long> sumy;
vector<int> wazne;
Func polacz(Func lewa, Func prawa) {
Func res;
res.m = (lewa.m * prawa.m) % MOD;
res.d = (lewa.d * prawa.m + prawa.d) % MOD;
return res;
}
Func pobierz(int a, int b) {
if (a > b) return { 1, 0 };
Func L = { 1, 0 };
Func P = { 1, 0 };
a += M; b += M;
L = tree[a];
if (a != b) P = tree[b];
while ((a / 2) != (b / 2)) {
if (a % 2 == 0) L = polacz(L, tree[a + 1]);
if (b % 2 == 1) P = polacz(tree[b - 1], P);
a /= 2; b /= 2;
}
return polacz(L, P);
}
long long zrob_zapytanie(long long x, int l, int r) {
int akutalny = l;
auto it = lower_bound(wazne.begin(), wazne.end(), akutalny);
while (it != wazne.end() && *it < r) {
int nast = *it;
x += (sumy[nast] - sumy[akutalny]);
Wydarznie w = wydarz[nast];
if (x + w.a > x * w.b) {
x += w.a;
}
else {
x *= w.b;
}
akutalny = nast + 1;
if (x >= MAX_VAL) {
if (akutalny < r) {
Func reszta = pobierz(akutalny, r - 1);
x %= MOD;
x = (x * reszta.m + reszta.d) % MOD;
}
return x % MOD;
}
it++;
}
x += (sumy[r] - sumy[akutalny]);
return x % MOD;
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n, q;
if (!(cin >> n >> q)) return 0;
wydarz.resize(n);
sumy.assign(n + 1, 0);
for (int i = 0; i < n; i++) {
cin >> wydarz[i].a >> wydarz[i].b;
sumy[i + 1] = sumy[i] + wydarz[i].a;
if (wydarz[i].b >= 2) wazne.push_back(i);
}
M = 1;
while (M < n) M *= 2;
for (int i = 0; i < M; i++) {
if (i < n) {
if (wydarz[i].b >= 2) tree[M + i] = { wydarz[i].b, 0 };
else tree[M + i] = { 1, wydarz[i].a };
}
else {
tree[M + i] = { 1, 0 };
}
}
for (int i = M - 1; i > 0; i--) tree[i] = polacz(tree[2 * i], tree[2 * i + 1]);
vector<long long> wyniki;
while (q--) {
long long x; int l, r;
cin >> x >> l >> r;
wyniki.push_back(zrob_zapytanie(x, l, r));
}
for (auto res : wyniki) cout << res << "\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 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 | #include <iostream> #include <vector> #include <algorithm> using namespace std; const long long MOD = 1e9 + 7; const long long MAX_VAL = 1e9; struct Func { long long m, d; }; struct Wydarznie { long long a, b; }; int M; Func tree[1048576]; vector<Wydarznie> wydarz; vector<long long> sumy; vector<int> wazne; Func polacz(Func lewa, Func prawa) { Func res; res.m = (lewa.m * prawa.m) % MOD; res.d = (lewa.d * prawa.m + prawa.d) % MOD; return res; } Func pobierz(int a, int b) { if (a > b) return { 1, 0 }; Func L = { 1, 0 }; Func P = { 1, 0 }; a += M; b += M; L = tree[a]; if (a != b) P = tree[b]; while ((a / 2) != (b / 2)) { if (a % 2 == 0) L = polacz(L, tree[a + 1]); if (b % 2 == 1) P = polacz(tree[b - 1], P); a /= 2; b /= 2; } return polacz(L, P); } long long zrob_zapytanie(long long x, int l, int r) { int akutalny = l; auto it = lower_bound(wazne.begin(), wazne.end(), akutalny); while (it != wazne.end() && *it < r) { int nast = *it; x += (sumy[nast] - sumy[akutalny]); Wydarznie w = wydarz[nast]; if (x + w.a > x * w.b) { x += w.a; } else { x *= w.b; } akutalny = nast + 1; if (x >= MAX_VAL) { if (akutalny < r) { Func reszta = pobierz(akutalny, r - 1); x %= MOD; x = (x * reszta.m + reszta.d) % MOD; } return x % MOD; } it++; } x += (sumy[r] - sumy[akutalny]); return x % MOD; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n, q; if (!(cin >> n >> q)) return 0; wydarz.resize(n); sumy.assign(n + 1, 0); for (int i = 0; i < n; i++) { cin >> wydarz[i].a >> wydarz[i].b; sumy[i + 1] = sumy[i] + wydarz[i].a; if (wydarz[i].b >= 2) wazne.push_back(i); } M = 1; while (M < n) M *= 2; for (int i = 0; i < M; i++) { if (i < n) { if (wydarz[i].b >= 2) tree[M + i] = { wydarz[i].b, 0 }; else tree[M + i] = { 1, wydarz[i].a }; } else { tree[M + i] = { 1, 0 }; } } for (int i = M - 1; i > 0; i--) tree[i] = polacz(tree[2 * i], tree[2 * i + 1]); vector<long long> wyniki; while (q--) { long long x; int l, r; cin >> x >> l >> r; wyniki.push_back(zrob_zapytanie(x, l, r)); } for (auto res : wyniki) cout << res << "\n"; return 0; } |
English