#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef double db;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define all(x) (x).begin(), (x).end()
#define sz(x) (x).size()
#define rep(i, l, r) for(int i=l; i<(r); i++)
const ll mod = 1e9 + 7;
ll suma(ll a, ll b) {
ll ans = a+b;
if(ans >= mod) ans -=mod;
return ans;
}
ll roznica(ll a, ll b) {
ll ans = a-b;
if(ans < 0) ans += mod;
return ans;
}
ll prod(ll a, ll b) {
return (a*b)%mod;
}
ll fastpo(ll a, ll b) {
ll ans = 1;
while(b) {
if(b&1) ans = prod(ans, a);
a = prod(a, a);
b/=2;
}
return ans;
}
ll inv(ll a) {
return fastpo(a, mod-2);
}
pll zlozenie(pll uno, pll dos) {
if(dos.first > 1) {
uno.first = prod(uno.first, dos.first);
uno.second = prod(uno.second, dos.first);
}
else uno.second = suma(uno.second, dos.second);
return uno;
}
pll cofniecie(pll uno, pll dos) { //zwraca dos - uno
ll c = prod(dos.first, inv(uno.first));
ll d = roznica(dos.second, prod(c, uno.second));
return {c, d};
}
const ll inf = 1e18;
void solve(){
int n, q;
cin >> n >> q;
vector<ll> a(n+1), b(n+1), prefa(n+1, 0), nastepny(n+1, inf);
vector<pll> pref2(n+1, make_pair(1ll, 0ll));
for(int i=1; i<=n; i++) {
cin >> a[i] >> b[i];
prefa[i] = a[i] + prefa[i-1];
}
ll nasthelp = inf;
for(int i=n; i>=0; --i) {
nastepny[i] = nasthelp;
if(b[i] > 1) nasthelp = i;
}
for(int i=1; i<=n; i++) {
pref2[i] = zlozenie(pref2[i-1], make_pair(b[i], a[i]));
}
//for(auto p : pref2) cout << p.first << " "<<p.second << "\n";
//cout << "\n\n";
while(q--) {
ll x;
int l, r;
cin >> x >> l >> r;
while(l < r && (x < mod)) {
ll nast_mnoz = nastepny[l];
if(nast_mnoz <= r) {
x += (prefa[nast_mnoz-1]-prefa[l]);
l = nast_mnoz-1;
if(x >= mod) break;
assert(b[l+1] > 1);
x = max(x*b[l+1], x+a[l+1]);
l++;
}
else {
x += prefa[r] - prefa[l];
l = r;
}
}
assert(x >= 0);
if(x>=mod) x%=mod;
if(l < r) {
//cout << "robie dodatkowy fun. aktualnie jest: "<<x << " "<<l<<" "<<r<<"\n";
x%=mod;
//cout << "bylo: "<<pref2[r].first << " "<<pref2[r].second << " || "<< pref2[l].first << " "<<pref2[l].second <<"\n";
pll fun = cofniecie(pref2[l], pref2[r]);
//cout << "dorabiam: "<<fun.first << " " << fun.second << "\n";
x = suma(prod(x, fun.first), fun.second);
}
cout << x << "\n";
}
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int t = 1;
while(t--){
solve();
}
}
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; typedef long long ll; typedef vector<int> vi; typedef double db; typedef pair<int, int> pii; typedef pair<ll, ll> pll; #define all(x) (x).begin(), (x).end() #define sz(x) (x).size() #define rep(i, l, r) for(int i=l; i<(r); i++) const ll mod = 1e9 + 7; ll suma(ll a, ll b) { ll ans = a+b; if(ans >= mod) ans -=mod; return ans; } ll roznica(ll a, ll b) { ll ans = a-b; if(ans < 0) ans += mod; return ans; } ll prod(ll a, ll b) { return (a*b)%mod; } ll fastpo(ll a, ll b) { ll ans = 1; while(b) { if(b&1) ans = prod(ans, a); a = prod(a, a); b/=2; } return ans; } ll inv(ll a) { return fastpo(a, mod-2); } pll zlozenie(pll uno, pll dos) { if(dos.first > 1) { uno.first = prod(uno.first, dos.first); uno.second = prod(uno.second, dos.first); } else uno.second = suma(uno.second, dos.second); return uno; } pll cofniecie(pll uno, pll dos) { //zwraca dos - uno ll c = prod(dos.first, inv(uno.first)); ll d = roznica(dos.second, prod(c, uno.second)); return {c, d}; } const ll inf = 1e18; void solve(){ int n, q; cin >> n >> q; vector<ll> a(n+1), b(n+1), prefa(n+1, 0), nastepny(n+1, inf); vector<pll> pref2(n+1, make_pair(1ll, 0ll)); for(int i=1; i<=n; i++) { cin >> a[i] >> b[i]; prefa[i] = a[i] + prefa[i-1]; } ll nasthelp = inf; for(int i=n; i>=0; --i) { nastepny[i] = nasthelp; if(b[i] > 1) nasthelp = i; } for(int i=1; i<=n; i++) { pref2[i] = zlozenie(pref2[i-1], make_pair(b[i], a[i])); } //for(auto p : pref2) cout << p.first << " "<<p.second << "\n"; //cout << "\n\n"; while(q--) { ll x; int l, r; cin >> x >> l >> r; while(l < r && (x < mod)) { ll nast_mnoz = nastepny[l]; if(nast_mnoz <= r) { x += (prefa[nast_mnoz-1]-prefa[l]); l = nast_mnoz-1; if(x >= mod) break; assert(b[l+1] > 1); x = max(x*b[l+1], x+a[l+1]); l++; } else { x += prefa[r] - prefa[l]; l = r; } } assert(x >= 0); if(x>=mod) x%=mod; if(l < r) { //cout << "robie dodatkowy fun. aktualnie jest: "<<x << " "<<l<<" "<<r<<"\n"; x%=mod; //cout << "bylo: "<<pref2[r].first << " "<<pref2[r].second << " || "<< pref2[l].first << " "<<pref2[l].second <<"\n"; pll fun = cofniecie(pref2[l], pref2[r]); //cout << "dorabiam: "<<fun.first << " " << fun.second << "\n"; x = suma(prod(x, fun.first), fun.second); } cout << x << "\n"; } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); int t = 1; while(t--){ solve(); } } |
English