#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <string>
using namespace std;
using ll = long long;
const int MOD = 1e9 + 7;
const int MAX = 500001;
struct node {
ll a, b;
node operator+(const node& rhs) {
return node{(a * rhs.b + rhs.a) % MOD, b * rhs.b % MOD};
}
};
class tree {
public:
tree(int n, ll *Ain, ll *Bin) {
for (size = 1; size < n; size *= 2);
V.resize(2 * size, node{0, 1});
for (int i = 0; i < n; i++) {
if (Bin[i] == 1) {
V[size + i].a = Ain[i];
} else {
V[size + i].b = Bin[i];
}
}
for (int i = size - 1; i > 0; i--) {
V[i] = V[2 * i] + V[2 * i + 1];
}
}
node get(int l, int r) { // [l, r)]
return _get(size + l, size + r);
}
private:
int size;
vector<node> V;
node _get(int l, int r) {
if (l + 1 == r) {
return V[l];
}
if (l % 2) {
return V[l] + _get(l + 1, r);
}
if (r % 2) {
return _get(l, r - 1) + V[r - 1];
}
return _get(l / 2, r / 2);
}
};
ll A[MAX], B[MAX], Asum[MAX];
int nextB2[MAX];
int n, m;
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> A[i] >> B[i];
Asum[i] = A[i] + (i ? Asum[i-1] : 0);
}
tree T(n, A, B);
nextB2[n] = n;
for (int i = n - 1; i >= 0; i--) {
if (B[i] == 1) {
nextB2[i] = nextB2[i+1];
} else {
nextB2[i] = i;
}
}
while (m--) {
ll x = 0;
int l, r;
cin >> x >> l >> r;
while (x < MOD && l < r) {
if (B[l] == 1) {
int nextb = min(nextB2[l] - 1, r - 1);
x += Asum[nextb] - (l ? Asum[l-1] : 0);
l = nextb + 1;
} else {
x = max(x + A[l], x * B[l]);
l++;
}
}
x %= MOD;
if (l < r) {
auto nd = T.get(l, r);
x = ((x * nd.b) + nd.a) % MOD;
}
cout << x << endl;
}
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 | #include <iostream> #include <vector> #include <algorithm> #include <map> #include <set> #include <cmath> #include <string> using namespace std; using ll = long long; const int MOD = 1e9 + 7; const int MAX = 500001; struct node { ll a, b; node operator+(const node& rhs) { return node{(a * rhs.b + rhs.a) % MOD, b * rhs.b % MOD}; } }; class tree { public: tree(int n, ll *Ain, ll *Bin) { for (size = 1; size < n; size *= 2); V.resize(2 * size, node{0, 1}); for (int i = 0; i < n; i++) { if (Bin[i] == 1) { V[size + i].a = Ain[i]; } else { V[size + i].b = Bin[i]; } } for (int i = size - 1; i > 0; i--) { V[i] = V[2 * i] + V[2 * i + 1]; } } node get(int l, int r) { // [l, r)] return _get(size + l, size + r); } private: int size; vector<node> V; node _get(int l, int r) { if (l + 1 == r) { return V[l]; } if (l % 2) { return V[l] + _get(l + 1, r); } if (r % 2) { return _get(l, r - 1) + V[r - 1]; } return _get(l / 2, r / 2); } }; ll A[MAX], B[MAX], Asum[MAX]; int nextB2[MAX]; int n, m; int main() { cin >> n >> m; for (int i = 0; i < n; i++) { cin >> A[i] >> B[i]; Asum[i] = A[i] + (i ? Asum[i-1] : 0); } tree T(n, A, B); nextB2[n] = n; for (int i = n - 1; i >= 0; i--) { if (B[i] == 1) { nextB2[i] = nextB2[i+1]; } else { nextB2[i] = i; } } while (m--) { ll x = 0; int l, r; cin >> x >> l >> r; while (x < MOD && l < r) { if (B[l] == 1) { int nextb = min(nextB2[l] - 1, r - 1); x += Asum[nextb] - (l ? Asum[l-1] : 0); l = nextb + 1; } else { x = max(x + A[l], x * B[l]); l++; } } x %= MOD; if (l < r) { auto nd = T.get(l, r); x = ((x * nd.b) + nd.a) % MOD; } cout << x << endl; } return 0; } |
English