#include <bits/stdc++.h>
using namespace std;
#define fwd(i, a, n) for (int i = (a); i < (n); i++)
#define rep(i, n) fwd(i, 0, n)
#define all(X) X.begin(), X.end()
#define sz(X) int(size(X))
#define pb push_back
#define eb emplace_back
#define st first
#define nd second
using pii = pair<int, int>; using vi = vector<int>;
using ll = long long; using ld = long double;
#ifdef LOC
auto SS = signal(6, [](int) { *(int *)0 = 0; });
#define DTP(x, y) auto operator << (auto &o, auto a) -> decltype(y, o) { o << "("; x; return o << ")"; }
DTP(o << a.st << ", " << a.nd, a.nd);
DTP(for (auto i : a) o << i << ", ", all(a));
void dump(auto... x) { (( cerr << x << ", " ), ...) <<
'\n'; }
#define deb(x...) cerr << setw(4) << __LINE__ << ":[" #x "]: ", dump(x)
#else
#define deb(...) 0
#endif
const ll MOD = 1e9 + 7;
ll modPow(ll a, ll b){
ll x = 1;
while(b > 0){
while(b % 2 == 0){
a = (a * a) % MOD;
b /= 2;
}
x = (x * a) % MOD;
b--;
}
return x;
}
ll modInv(ll a){
return modPow(a, MOD - 2);
}
pair<ll, ll> operator*(pair<ll, ll> a, pair<ll, ll> b){
return {(a.st * b.st) % MOD, (a.nd * b.st + b.nd) % MOD};
}
pair<ll, ll> inv(pair<ll, ll> a){
ll x = modInv(a.st);
ll y = (-a.nd * x) % MOD;
if(y < 0)y += MOD;
return {x, y};
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout << fixed << setprecision(10);
int n, q; cin >> n >> q;
vector<ll> a(n), b(n);
rep(i, n)cin >> a[i] >> b[i];
vector<pair<ll, ll>> v(n);
rep(i, n){
if(b[i] <= 1)v[i] = {1, a[i]};
else v[i] = {b[i], 0};
}
vector<pair<ll, ll>> suf(n+1), invSuf(n+1);
suf[n] = {1, 0};
invSuf[n] = {1, 0};
for(int i = n-1; i >= 0; i--){
suf[i] = v[i] * suf[i+1];
}
invSuf[0] = inv(suf[0]);
for(int i = 1; i < n; i++){
invSuf[i] = invSuf[i-1] * v[i-1];
}
//applying every element in range [l, r) with assumption that mul by > 1 better than adding
auto rangeTransform = [&](int l, int r){
return suf[l] * invSuf[r];
};
//this is not modulo 1e9+7. Need to know how big
vector<ll> sufSum(n+1);
sufSum[n] = 0;
for(int i = n-1; i >= 0; i--)sufSum[i] = sufSum[i+1] + a[i];
deb(suf);
deb(invSuf);
deb(sufSum);
//once again interval like this [l, r)
auto rangeSum = [&](int l, int r){
return sufSum[l] - sufSum[r];
};
vector<int> nxtB(n+1), nxtA(n+1); //nxt b > 1 and a > 0
nxtB[n] = nxtA[n] = n;
for(int i = n-1; i >= 0; i--){
nxtA[i] = nxtA[i+1];
nxtB[i] = nxtB[i+1];
if(a[i] > 0)nxtA[i] = i;
if(b[i] > 1)nxtB[i] = i;
}
deb(nxtA);
deb(nxtB);
while(q--){
ll x;
int l, r;
cin >> x >> l >> r;
int pos = l;
//make sure value is positive after first costly operation
if(x == 0){
pos = min(r, nxtA[l]);
}
bool big = false;
while(pos < r && !big){
deb(pos);
int nxt = nxtB[pos];
if(nxt > r)nxt = r;
if(nxt == pos){//consider b
x = max(x + a[pos], x * b[pos]);
pos++;
}else{
x += rangeSum(pos, nxt);
pos = nxt;
}
if(x >= MOD){
x %= MOD;
big = true;
}
}
pair<ll, ll> transform = rangeTransform(pos, r);
x %= MOD;
x = (x * transform.st + transform.nd) % 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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | #include <bits/stdc++.h> using namespace std; #define fwd(i, a, n) for (int i = (a); i < (n); i++) #define rep(i, n) fwd(i, 0, n) #define all(X) X.begin(), X.end() #define sz(X) int(size(X)) #define pb push_back #define eb emplace_back #define st first #define nd second using pii = pair<int, int>; using vi = vector<int>; using ll = long long; using ld = long double; #ifdef LOC auto SS = signal(6, [](int) { *(int *)0 = 0; }); #define DTP(x, y) auto operator << (auto &o, auto a) -> decltype(y, o) { o << "("; x; return o << ")"; } DTP(o << a.st << ", " << a.nd, a.nd); DTP(for (auto i : a) o << i << ", ", all(a)); void dump(auto... x) { (( cerr << x << ", " ), ...) << '\n'; } #define deb(x...) cerr << setw(4) << __LINE__ << ":[" #x "]: ", dump(x) #else #define deb(...) 0 #endif const ll MOD = 1e9 + 7; ll modPow(ll a, ll b){ ll x = 1; while(b > 0){ while(b % 2 == 0){ a = (a * a) % MOD; b /= 2; } x = (x * a) % MOD; b--; } return x; } ll modInv(ll a){ return modPow(a, MOD - 2); } pair<ll, ll> operator*(pair<ll, ll> a, pair<ll, ll> b){ return {(a.st * b.st) % MOD, (a.nd * b.st + b.nd) % MOD}; } pair<ll, ll> inv(pair<ll, ll> a){ ll x = modInv(a.st); ll y = (-a.nd * x) % MOD; if(y < 0)y += MOD; return {x, y}; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(10); int n, q; cin >> n >> q; vector<ll> a(n), b(n); rep(i, n)cin >> a[i] >> b[i]; vector<pair<ll, ll>> v(n); rep(i, n){ if(b[i] <= 1)v[i] = {1, a[i]}; else v[i] = {b[i], 0}; } vector<pair<ll, ll>> suf(n+1), invSuf(n+1); suf[n] = {1, 0}; invSuf[n] = {1, 0}; for(int i = n-1; i >= 0; i--){ suf[i] = v[i] * suf[i+1]; } invSuf[0] = inv(suf[0]); for(int i = 1; i < n; i++){ invSuf[i] = invSuf[i-1] * v[i-1]; } //applying every element in range [l, r) with assumption that mul by > 1 better than adding auto rangeTransform = [&](int l, int r){ return suf[l] * invSuf[r]; }; //this is not modulo 1e9+7. Need to know how big vector<ll> sufSum(n+1); sufSum[n] = 0; for(int i = n-1; i >= 0; i--)sufSum[i] = sufSum[i+1] + a[i]; deb(suf); deb(invSuf); deb(sufSum); //once again interval like this [l, r) auto rangeSum = [&](int l, int r){ return sufSum[l] - sufSum[r]; }; vector<int> nxtB(n+1), nxtA(n+1); //nxt b > 1 and a > 0 nxtB[n] = nxtA[n] = n; for(int i = n-1; i >= 0; i--){ nxtA[i] = nxtA[i+1]; nxtB[i] = nxtB[i+1]; if(a[i] > 0)nxtA[i] = i; if(b[i] > 1)nxtB[i] = i; } deb(nxtA); deb(nxtB); while(q--){ ll x; int l, r; cin >> x >> l >> r; int pos = l; //make sure value is positive after first costly operation if(x == 0){ pos = min(r, nxtA[l]); } bool big = false; while(pos < r && !big){ deb(pos); int nxt = nxtB[pos]; if(nxt > r)nxt = r; if(nxt == pos){//consider b x = max(x + a[pos], x * b[pos]); pos++; }else{ x += rangeSum(pos, nxt); pos = nxt; } if(x >= MOD){ x %= MOD; big = true; } } pair<ll, ll> transform = rangeTransform(pos, r); x %= MOD; x = (x * transform.st + transform.nd) % MOD; cout << x << "\n"; } return 0; } |
English