#include <bits/stdc++.h>
using namespace std;
const int mod = 1'000'000'007;
struct seg_tree {
vector<int64_t> data, data2;
int base;
seg_tree(const vector<pair<int, int>>& in) {
base = (int)bit_ceil(in.size());
data.resize(2 * base);
data2.resize(2 * base);
for (int i = 0; i < (int)in.size(); ++i) {
data[base + i] = in[i].second;
data2[base + i] = (in[i].second == 1 ? in[i].first : 0);
}
for (int i = base - 1; i >= 1; --i) {
data[i] = data[2 * i] * data[2 * i + 1] % mod;
data2[i] = (data2[2 * i] * data[2 * i + 1] + data2[2 * i + 1]) % mod;
}
}
pair<int64_t, int64_t> _query(int a, int b, int v, int l, int r) {
if (b < l || r < a) {
return {1, 0};
}
if (a <= l && r <= b) {
return {data[v], data2[v]};
}
int mid = (l + r) / 2;
auto [L1, L2] = _query(a, b, 2 * v, l, mid);
auto [R1, R2] = _query(a, b, 2 * v + 1, mid + 1, r);
return {L1 * R1 % mod, (L2 * R1 + R2) % mod};
}
int64_t query(int64_t x, int a, int b) {
if (a > b) {
return x % mod;
}
auto [r1, r2] = _query(a, b, 1, 0, base - 1);
return (x * r1 + r2) % mod;
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<pair<int, int>> events(n);
for (auto& [a, b] : events) {
cin >> a >> b;
}
vector<int64_t> pref(n);
for (int i = 0; i < n; ++i) {
pref[i] = (i ? pref[i - 1] : 0) + events[i].first;
}
auto get_sum = [pref](int l, int r) {
return pref[r] - (l ? pref[l - 1] : 0);
};
vector<int> zeroes(n + 1), ones(n + 1);
zeroes[n] = n;
ones[n] = n;
for (int i = n - 1; i >= 0; --i) {
if (events[i].second == 1) {
ones[i] = ones[i + 1];
}
else {
ones[i] = i;
}
if (events[i].first == 0) {
zeroes[i] = zeroes[i + 1];
}
else {
zeroes[i] = i;
}
}
seg_tree T(events);
for (int i = 0; i < q; ++i) {
int64_t x;
int l, r;
cin >> x >> l >> r;
if (x == 0) {
l = zeroes[l];
}
while (l < r) {
auto [a, b] = events[l];
if (b == 1) {
x += get_sum(l, min(r, ones[l]) - 1);
l = min(r, ones[l]);
continue;
}
if (x > mod) {
x %= mod;
break;
}
++l;
x = max(x + a, b * x);
if (x > mod) {
x %= mod;
break;
}
}
cout << T.query(x, l, r - 1) << '\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 | #include <bits/stdc++.h> using namespace std; const int mod = 1'000'000'007; struct seg_tree { vector<int64_t> data, data2; int base; seg_tree(const vector<pair<int, int>>& in) { base = (int)bit_ceil(in.size()); data.resize(2 * base); data2.resize(2 * base); for (int i = 0; i < (int)in.size(); ++i) { data[base + i] = in[i].second; data2[base + i] = (in[i].second == 1 ? in[i].first : 0); } for (int i = base - 1; i >= 1; --i) { data[i] = data[2 * i] * data[2 * i + 1] % mod; data2[i] = (data2[2 * i] * data[2 * i + 1] + data2[2 * i + 1]) % mod; } } pair<int64_t, int64_t> _query(int a, int b, int v, int l, int r) { if (b < l || r < a) { return {1, 0}; } if (a <= l && r <= b) { return {data[v], data2[v]}; } int mid = (l + r) / 2; auto [L1, L2] = _query(a, b, 2 * v, l, mid); auto [R1, R2] = _query(a, b, 2 * v + 1, mid + 1, r); return {L1 * R1 % mod, (L2 * R1 + R2) % mod}; } int64_t query(int64_t x, int a, int b) { if (a > b) { return x % mod; } auto [r1, r2] = _query(a, b, 1, 0, base - 1); return (x * r1 + r2) % mod; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin >> n >> q; vector<pair<int, int>> events(n); for (auto& [a, b] : events) { cin >> a >> b; } vector<int64_t> pref(n); for (int i = 0; i < n; ++i) { pref[i] = (i ? pref[i - 1] : 0) + events[i].first; } auto get_sum = [pref](int l, int r) { return pref[r] - (l ? pref[l - 1] : 0); }; vector<int> zeroes(n + 1), ones(n + 1); zeroes[n] = n; ones[n] = n; for (int i = n - 1; i >= 0; --i) { if (events[i].second == 1) { ones[i] = ones[i + 1]; } else { ones[i] = i; } if (events[i].first == 0) { zeroes[i] = zeroes[i + 1]; } else { zeroes[i] = i; } } seg_tree T(events); for (int i = 0; i < q; ++i) { int64_t x; int l, r; cin >> x >> l >> r; if (x == 0) { l = zeroes[l]; } while (l < r) { auto [a, b] = events[l]; if (b == 1) { x += get_sum(l, min(r, ones[l]) - 1); l = min(r, ones[l]); continue; } if (x > mod) { x %= mod; break; } ++l; x = max(x + a, b * x); if (x > mod) { x %= mod; break; } } cout << T.query(x, l, r - 1) << '\n'; } return 0; } |
English