#include <bits/stdc++.h>
#define rep(i, a, b) for(ll i = a; i < b; i++)
#define per(i, a, b) for(ll i = a; i >= b; i--)
#define all(v) begin(v), end(v)
#define st first
#define nd second
using namespace std;
using ll = long long;
using bigi = __int128;
using pii = pair<ll, ll>;
const ll N = 5e5 + 5;
const ll P = 1 << 19;
const ll D = P * 2 + 5;
const ll M = 1e9 + 7;
ll drzb[D], drz[D];
ll ai[N], bi[N];
ll pre[N];
void init(ll n){
rep(i, P, D){
drzb[i] = 1;
}
rep(i, 1, n + 1){
drzb[P + i] = bi[i];
if(bi[i] == 1){
drz[P + i] = ai[i];
}
}
per(i, P - 1, 1){
drzb[i] = drzb[i * 2] * drzb[i * 2 + 1] % M;
drz[i] = (drz[i * 2] * drzb[i * 2 + 1] + drz[i * 2 + 1]) % M;
}
}
ll Query(ll i, ll j){
i += P; j += P;
ll odp0 = 0, odp1 = 0, ilb = 1;
while(i <= j){
if(i % 2 == 1){
odp0 = (odp0 * drzb[i] + drz[i]) % M;
}
if(j % 2 == 0){
odp1 = (drz[j] * ilb + odp1) % M;
ilb = (ilb * drzb[j]) % M;
}
i = (i + 1) / 2;
j = (j - 1) / 2;
}
return (odp0 * ilb + odp1) % M;
}
ll Queryb(ll i, ll j){
i += P; j += P;
ll odp = 1;
while(i <= j){
if(i % 2 == 1) odp = odp * drzb[i] % M;
if(j % 2 == 0) odp = odp * drzb[j] % M;
i = (i + 1)/ 2;
j = (j - 1)/ 2;
}
return odp;
}
vector<ll> na, nb;
void solve(ll n){
ll x, l, r;
cin >> x >> l >> r;
l++;
if(!x){
l = lower_bound(all(na), l) - na.begin();
if(l >= na.size()){
cout << 0 << '\n';
return;
}
l = na[l];
if(l > r){
cout << 0 << '\n';
return;
}
x = ai[l];
l++;
}
ll lb = lower_bound(all(nb), l) - nb.begin();
ll lbb = min(ll(upper_bound(all(nb), r) - nb.begin()), lb + 30);
ll prze = l - 1;
ll odp = x;
rep(i, lb, lbb){
odp += pre[nb[i] - 1] - pre[prze];
if(odp * bi[nb[i]] > odp + ai[nb[i]]){
odp *= bi[nb[i]];
}
else{
odp += ai[nb[i]];
}
prze = nb[i];
if(odp >= M){
break;
}
}
odp %= M;
cout << (odp * Queryb(prze + 1, r) + Query(prze + 1, r)) % M << '\n';
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
ll n, q;
cin >> n >> q;
rep(i, 1, n + 1){
cin >> ai[i] >> bi[i];
if(ai[i]) na.push_back(i);
if(bi[i] > 1) nb.push_back(i);
}
rep(i, 1, n + 1){
pre[i] = (pre[i - 1] + ai[i]) % M;
}
init(n);
while(q--){
solve(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 | #include <bits/stdc++.h> #define rep(i, a, b) for(ll i = a; i < b; i++) #define per(i, a, b) for(ll i = a; i >= b; i--) #define all(v) begin(v), end(v) #define st first #define nd second using namespace std; using ll = long long; using bigi = __int128; using pii = pair<ll, ll>; const ll N = 5e5 + 5; const ll P = 1 << 19; const ll D = P * 2 + 5; const ll M = 1e9 + 7; ll drzb[D], drz[D]; ll ai[N], bi[N]; ll pre[N]; void init(ll n){ rep(i, P, D){ drzb[i] = 1; } rep(i, 1, n + 1){ drzb[P + i] = bi[i]; if(bi[i] == 1){ drz[P + i] = ai[i]; } } per(i, P - 1, 1){ drzb[i] = drzb[i * 2] * drzb[i * 2 + 1] % M; drz[i] = (drz[i * 2] * drzb[i * 2 + 1] + drz[i * 2 + 1]) % M; } } ll Query(ll i, ll j){ i += P; j += P; ll odp0 = 0, odp1 = 0, ilb = 1; while(i <= j){ if(i % 2 == 1){ odp0 = (odp0 * drzb[i] + drz[i]) % M; } if(j % 2 == 0){ odp1 = (drz[j] * ilb + odp1) % M; ilb = (ilb * drzb[j]) % M; } i = (i + 1) / 2; j = (j - 1) / 2; } return (odp0 * ilb + odp1) % M; } ll Queryb(ll i, ll j){ i += P; j += P; ll odp = 1; while(i <= j){ if(i % 2 == 1) odp = odp * drzb[i] % M; if(j % 2 == 0) odp = odp * drzb[j] % M; i = (i + 1)/ 2; j = (j - 1)/ 2; } return odp; } vector<ll> na, nb; void solve(ll n){ ll x, l, r; cin >> x >> l >> r; l++; if(!x){ l = lower_bound(all(na), l) - na.begin(); if(l >= na.size()){ cout << 0 << '\n'; return; } l = na[l]; if(l > r){ cout << 0 << '\n'; return; } x = ai[l]; l++; } ll lb = lower_bound(all(nb), l) - nb.begin(); ll lbb = min(ll(upper_bound(all(nb), r) - nb.begin()), lb + 30); ll prze = l - 1; ll odp = x; rep(i, lb, lbb){ odp += pre[nb[i] - 1] - pre[prze]; if(odp * bi[nb[i]] > odp + ai[nb[i]]){ odp *= bi[nb[i]]; } else{ odp += ai[nb[i]]; } prze = nb[i]; if(odp >= M){ break; } } odp %= M; cout << (odp * Queryb(prze + 1, r) + Query(prze + 1, r)) % M << '\n'; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); ll n, q; cin >> n >> q; rep(i, 1, n + 1){ cin >> ai[i] >> bi[i]; if(ai[i]) na.push_back(i); if(bi[i] > 1) nb.push_back(i); } rep(i, 1, n + 1){ pre[i] = (pre[i - 1] + ai[i]) % M; } init(n); while(q--){ solve(n); } } |
English