#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1e9 + 7;
const int N = 5e5 + 99;
const ll sensownyLimit = 1e9 + 29;
int mn[N];
ll sum[N];
int wcz[N];
int pow_mod(int a, int b){
int x = a, w = 1;
while(b > 0){
if(b & 1){
w = (1LL * w * x) % mod;
}
x = (1LL * x * x) % mod;
b /= 2;
}
return w;
}
int modular_inverse(int a){
return pow_mod(a,mod - 2);
}
int A[N], B[N];
int od_do(int a, int b){
return (1LL * mn[b] * modular_inverse(mn[a-1])) % mod;
}
int wzorek(int l, int r){
ll x = od_do(l,r) * 1LL * wcz[l-1];
x %= mod;
x = wcz[r] - x;
x %= mod;
x += mod;
x %= mod;
return x;
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n, q;
cin >> n >> q;
mn[0] = 1; // liczba neutralna dla mnozenia
sum[0] = 0; // liczba neutralna dla dodawania
vector<int>nonOne;
for(int i = 1; i <= n; i++){
int a, b;
cin >> a >> b;
A[i] = a;
B[i] = b;
if(b == 1){
wcz[i] = (wcz[i-1] + a) % mod;
}
else{
nonOne.push_back(i);
wcz[i] = (1LL * wcz[i-1] * b) % mod;
}
sum[i] = (sum[i-1] + a);
mn[i] = (1LL * mn[i-1] * b) % mod;
}
while(q--){
ll w;
cin >> w;
int l, r;
cin >> l >> r;
l++;
//na poczatku log_2(mod) razy, przejde po bi ≠ 1
//bin-search po wynik
int ite = lower_bound(nonOne.begin(),nonOne.end(),l) - nonOne.begin();
int last = l-1;
for(int i = ite; (i < (int)nonOne.size()) && (w < sensownyLimit) && (nonOne[i] <= r); i++){
int wh = nonOne[i];
// cout << wh << "; ";
// cout << (sum[wh-1] - sum[last]) << " = = = " << (sum[wh-1] - sum[last]) << '\n';
w += (sum[wh-1] - sum[last]);
last = wh;
w = max(w + A[wh], w * B[wh]);
}
// cout << "xd " << endl;
l = last + 1;
// cout << l << " " << r << '\n';
// cout << "dotychaczaosw w = " << w << endl;
if(l > r){
// cout << "DZD\n";
cout << w % mod << '\n';
continue;
}
// cout << "l, r = " << l << ", " << r << endl;
w %= mod;
w = (1LL * w * od_do(l, r))%mod;
// cout << "od do " << od_do(l,r) << '\n';
w += (wzorek(l,r));
w %= mod;
w += mod;
w %= mod;
cout << w << '\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 | #include<bits/stdc++.h> using namespace std; using ll = long long; const int mod = 1e9 + 7; const int N = 5e5 + 99; const ll sensownyLimit = 1e9 + 29; int mn[N]; ll sum[N]; int wcz[N]; int pow_mod(int a, int b){ int x = a, w = 1; while(b > 0){ if(b & 1){ w = (1LL * w * x) % mod; } x = (1LL * x * x) % mod; b /= 2; } return w; } int modular_inverse(int a){ return pow_mod(a,mod - 2); } int A[N], B[N]; int od_do(int a, int b){ return (1LL * mn[b] * modular_inverse(mn[a-1])) % mod; } int wzorek(int l, int r){ ll x = od_do(l,r) * 1LL * wcz[l-1]; x %= mod; x = wcz[r] - x; x %= mod; x += mod; x %= mod; return x; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n, q; cin >> n >> q; mn[0] = 1; // liczba neutralna dla mnozenia sum[0] = 0; // liczba neutralna dla dodawania vector<int>nonOne; for(int i = 1; i <= n; i++){ int a, b; cin >> a >> b; A[i] = a; B[i] = b; if(b == 1){ wcz[i] = (wcz[i-1] + a) % mod; } else{ nonOne.push_back(i); wcz[i] = (1LL * wcz[i-1] * b) % mod; } sum[i] = (sum[i-1] + a); mn[i] = (1LL * mn[i-1] * b) % mod; } while(q--){ ll w; cin >> w; int l, r; cin >> l >> r; l++; //na poczatku log_2(mod) razy, przejde po bi ≠ 1 //bin-search po wynik int ite = lower_bound(nonOne.begin(),nonOne.end(),l) - nonOne.begin(); int last = l-1; for(int i = ite; (i < (int)nonOne.size()) && (w < sensownyLimit) && (nonOne[i] <= r); i++){ int wh = nonOne[i]; // cout << wh << "; "; // cout << (sum[wh-1] - sum[last]) << " = = = " << (sum[wh-1] - sum[last]) << '\n'; w += (sum[wh-1] - sum[last]); last = wh; w = max(w + A[wh], w * B[wh]); } // cout << "xd " << endl; l = last + 1; // cout << l << " " << r << '\n'; // cout << "dotychaczaosw w = " << w << endl; if(l > r){ // cout << "DZD\n"; cout << w % mod << '\n'; continue; } // cout << "l, r = " << l << ", " << r << endl; w %= mod; w = (1LL * w * od_do(l, r))%mod; // cout << "od do " << od_do(l,r) << '\n'; w += (wzorek(l,r)); w %= mod; w += mod; w %= mod; cout << w << '\n'; } } |
English