#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, q;
ll a[500'007];
ll b[500'007];
// pair<ll,ll> ph;
ll x, linp, rinp;
struct Node {
ll B, A;
};
const ll MOD = 1e9+7;
ll prefA[500'007];
vector<ll> ind; // b[i] > 1
Node tree[2'000'007];
// f2(f1(x))
Node Merge(Node l, Node r) {
Node res;
res.B = (l.B * r.B) % MOD;
res.A = (l.A * r.B + r.A) % MOD;
return res;
}
void Build(ll node, ll l, ll r) {
if (l == r) {
if (b[l] > 1) {
tree[node] = {b[l],0};
} else {
tree[node] = {1, a[l]};
}
return;
}
ll mid = (l+r)/2;
Build(2*node, l, mid);
Build(2*node+1, mid+1, r);
tree[node] = Merge(tree[2*node], tree[2*node+1]);
}
Node Query(ll node, ll l, ll r, ll ls, ll rs) {
if (r < ls || l > rs) return {1,0}; // neutralne
if (l >= ls && r <= rs) return tree[node];
ll mid = (l+r)/2;
return Merge(Query(node*2, l, mid, ls, rs), Query(node*2+1, mid+1, r, ls, rs));
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
cin >> n >> q;
for (ll i=1; i<=n; i++) {
cin >> a[i] >> b[i];
prefA[i] = (prefA[i-1] + a[i]) % MOD;
if (b[i] > 1) ind.push_back(i);
}
Build(1,1,n);
for (ll _=0; _<q; _++) {
cin >> x >> linp >> rinp;
linp++;
ll curr = linp;
bool prog=false;
while (curr <= rinp) {
// najblizsze b[i]>1
auto it = lower_bound(ind.begin(),ind.end(),curr);
if (it == ind.end() || *it > rinp) {
x = (x + (prefA[rinp]-prefA[linp-1]+MOD)%MOD)%MOD;
curr = rinp+1;
} else {
ll next = *it;
x = (x + (prefA[next-1]-prefA[curr-1]+MOD)%MOD)%MOD;
// jesli >= MOD to zawsze mnoz
if (x >= MOD || x * b[next] >= x + a[next]) {
x = (x*b[next]) % MOD;
} else {
x = (x+a[next]) % MOD;
}
curr = next+1;
}
if (x >= MOD) {
x %= MOD;
prog = true;
break;
}
}
if (prog && curr <= rinp) {
Node fin = Query(1,1,n,curr,rinp);
x = (x * fin.B + fin.A) % MOD;
}
x %= MOD;
cout << x << "\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 120 | #include <bits/stdc++.h> using namespace std; #define ll long long ll n, q; ll a[500'007]; ll b[500'007]; // pair<ll,ll> ph; ll x, linp, rinp; struct Node { ll B, A; }; const ll MOD = 1e9+7; ll prefA[500'007]; vector<ll> ind; // b[i] > 1 Node tree[2'000'007]; // f2(f1(x)) Node Merge(Node l, Node r) { Node res; res.B = (l.B * r.B) % MOD; res.A = (l.A * r.B + r.A) % MOD; return res; } void Build(ll node, ll l, ll r) { if (l == r) { if (b[l] > 1) { tree[node] = {b[l],0}; } else { tree[node] = {1, a[l]}; } return; } ll mid = (l+r)/2; Build(2*node, l, mid); Build(2*node+1, mid+1, r); tree[node] = Merge(tree[2*node], tree[2*node+1]); } Node Query(ll node, ll l, ll r, ll ls, ll rs) { if (r < ls || l > rs) return {1,0}; // neutralne if (l >= ls && r <= rs) return tree[node]; ll mid = (l+r)/2; return Merge(Query(node*2, l, mid, ls, rs), Query(node*2+1, mid+1, r, ls, rs)); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> q; for (ll i=1; i<=n; i++) { cin >> a[i] >> b[i]; prefA[i] = (prefA[i-1] + a[i]) % MOD; if (b[i] > 1) ind.push_back(i); } Build(1,1,n); for (ll _=0; _<q; _++) { cin >> x >> linp >> rinp; linp++; ll curr = linp; bool prog=false; while (curr <= rinp) { // najblizsze b[i]>1 auto it = lower_bound(ind.begin(),ind.end(),curr); if (it == ind.end() || *it > rinp) { x = (x + (prefA[rinp]-prefA[linp-1]+MOD)%MOD)%MOD; curr = rinp+1; } else { ll next = *it; x = (x + (prefA[next-1]-prefA[curr-1]+MOD)%MOD)%MOD; // jesli >= MOD to zawsze mnoz if (x >= MOD || x * b[next] >= x + a[next]) { x = (x*b[next]) % MOD; } else { x = (x+a[next]) % MOD; } curr = next+1; } if (x >= MOD) { x %= MOD; prog = true; break; } } if (prog && curr <= rinp) { Node fin = Query(1,1,n,curr,rinp); x = (x * fin.B + fin.A) % MOD; } x %= MOD; cout << x << "\n"; } return 0; } |
English