#include <bits/stdc++.h>
using namespace std;
#define st first
#define nd second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define BOOST ios_base::sync_with_stdio(0), cin.tie(0)
template<typename T>
using vc = vector<T>;
using ll = long long;
using ld = long double;
using ii = pair<int, int>;
constexpr int modulo = 1e9 + 7;
template<int MOD>
struct mod{
int val;
mod(ll x = 0){x%=MOD; if(x<0)x+=MOD; val=x;}
mod operator+(const mod& x) const{return mod(val+x.val);}
mod operator-(const mod& x) const{return mod(val-x.val);}
mod operator*(const mod& x) const{return mod(1ll*val*x.val);}
mod operator/(const mod& x) const{return *this*x.power(-1);}
mod& operator+=(const mod& x){return *this=*this+x;}
mod& operator-=(const mod& x){return *this=*this-x;}
mod& operator*=(const mod& x){return *this=*this*x;}
mod& operator/=(const mod& x){return *this=*this/x;}
bool operator==(const mod& x) const{return val==x.val;}
bool operator!=(const mod& x) const{return val!=x.val;}
friend std::ostream& operator<<(std::ostream& out, const mod& x){return out << x.val;}
mod power(int p) const{
mod x = *this;
if(p < 0) return x.power(-p).power(MOD-2);
mod res = {1};
for(; p; p>>=1){
if(p&1) res *= x;
x *= x;
}
return res;
}
};
using mint = mod<(int)modulo>;
const int N = 5e5 + 5;
pair<int, int> t[N];
ll pref[N];
pair<mint, mint> suf[N];
int nxt[N];
ll seg(int a, int b){ // wyłącznie
if(a >= b) return 0;
if(a == 0) return pref[b-1];
return pref[b-1] - pref[a-1];
}
mint go(ll cur, int l, int r){ // akcje [l, r)
while(l < r){
if(cur > modulo) break;
if(t[l].nd == 1){
int jump = min(r, nxt[l]);
cur += seg(l, jump);
l = jump;
continue;
}
if(cur + t[l].st > cur * t[l].nd){
cur += t[l].st;
}
else{
cur *= t[l].nd;
}
l++;
}
mint res = cur;
if(l < r){
res *= suf[l].nd / suf[r].nd;
res += (suf[l].st - suf[r].st) / suf[r].nd;
}
return res;
}
int main(){
BOOST;
int n, q;
cin >> n >> q;
for(int i=0; i<n; i++){
cin >> t[i].st >> t[i].nd;
pref[i] = t[i].st;
if(i) pref[i] += pref[i-1];
}
suf[n] = {0, 1};
for(int i=n-1; i>=0; i--){
suf[i] = suf[i+1];
if(t[i].nd == 1){
suf[i].st += suf[i].nd * t[i].st;
}
else{
suf[i].nd *= t[i].nd;
}
}
nxt[n-1] = n;
for(int i=n-2; i>=0; i--){
nxt[i] = nxt[i+1];
if(t[i+1].nd > 1) nxt[i] = i+1;
}
for(int i=0; i<q; i++){
int x, l, r;
cin >> x >> l >> r;
cout << go(x, l, r) << "\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 118 119 120 | #include <bits/stdc++.h> using namespace std; #define st first #define nd second #define pb push_back #define all(x) (x).begin(), (x).end() #define BOOST ios_base::sync_with_stdio(0), cin.tie(0) template<typename T> using vc = vector<T>; using ll = long long; using ld = long double; using ii = pair<int, int>; constexpr int modulo = 1e9 + 7; template<int MOD> struct mod{ int val; mod(ll x = 0){x%=MOD; if(x<0)x+=MOD; val=x;} mod operator+(const mod& x) const{return mod(val+x.val);} mod operator-(const mod& x) const{return mod(val-x.val);} mod operator*(const mod& x) const{return mod(1ll*val*x.val);} mod operator/(const mod& x) const{return *this*x.power(-1);} mod& operator+=(const mod& x){return *this=*this+x;} mod& operator-=(const mod& x){return *this=*this-x;} mod& operator*=(const mod& x){return *this=*this*x;} mod& operator/=(const mod& x){return *this=*this/x;} bool operator==(const mod& x) const{return val==x.val;} bool operator!=(const mod& x) const{return val!=x.val;} friend std::ostream& operator<<(std::ostream& out, const mod& x){return out << x.val;} mod power(int p) const{ mod x = *this; if(p < 0) return x.power(-p).power(MOD-2); mod res = {1}; for(; p; p>>=1){ if(p&1) res *= x; x *= x; } return res; } }; using mint = mod<(int)modulo>; const int N = 5e5 + 5; pair<int, int> t[N]; ll pref[N]; pair<mint, mint> suf[N]; int nxt[N]; ll seg(int a, int b){ // wyłącznie if(a >= b) return 0; if(a == 0) return pref[b-1]; return pref[b-1] - pref[a-1]; } mint go(ll cur, int l, int r){ // akcje [l, r) while(l < r){ if(cur > modulo) break; if(t[l].nd == 1){ int jump = min(r, nxt[l]); cur += seg(l, jump); l = jump; continue; } if(cur + t[l].st > cur * t[l].nd){ cur += t[l].st; } else{ cur *= t[l].nd; } l++; } mint res = cur; if(l < r){ res *= suf[l].nd / suf[r].nd; res += (suf[l].st - suf[r].st) / suf[r].nd; } return res; } int main(){ BOOST; int n, q; cin >> n >> q; for(int i=0; i<n; i++){ cin >> t[i].st >> t[i].nd; pref[i] = t[i].st; if(i) pref[i] += pref[i-1]; } suf[n] = {0, 1}; for(int i=n-1; i>=0; i--){ suf[i] = suf[i+1]; if(t[i].nd == 1){ suf[i].st += suf[i].nd * t[i].st; } else{ suf[i].nd *= t[i].nd; } } nxt[n-1] = n; for(int i=n-2; i>=0; i--){ nxt[i] = nxt[i+1]; if(t[i+1].nd > 1) nxt[i] = i+1; } for(int i=0; i<q; i++){ int x, l, r; cin >> x >> l >> r; cout << go(x, l, r) << "\n"; } } |
English