#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
constexpr ll mod = 1000000007;
ll euclid(ll a, ll b, ll &x, ll &y) {
if (!b) return x = 1, y = 0, a;
ll d = euclid(b, a % b, y, x);
return y -= a/b * x, d;
}
struct Mod {
ll x;
Mod(ll xx) : x(xx) {}
Mod operator+(Mod b) { return Mod((x + b.x) % mod); }
Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); }
Mod operator*(Mod b) { return Mod((x * b.x) % mod); }
Mod operator/(Mod b) { return *this * invert(b); }
Mod invert(Mod a) {
ll x, y, g = euclid(a.x, mod, x, y);
assert(g == 1); return Mod((x + mod) % mod);
}
Mod operator^(ll e) {
if (!e) return Mod(1);
Mod r = *this ^ (e / 2); r = r * r;
return e&1 ? *this * r : r;
}
};
void solve() {
int n, q;
cin >> n >> q;
vector<pair<ll, ll>> vs(n);
for(auto& [a, b] : vs) {
cin >> b >> a;
}
vector<pair<Mod, Mod>> pref;
pref.push_back(vs[0]);
for(int i = 1; i < n; i++) {
auto [a, b] = vs[i];
if(a == 1) {
pref.emplace_back(pref.back().first, pref.back().second + b);
}
else {
pref.emplace_back(pref.back().first * a, pref.back().second * a);
}
}
auto get = [&] (int l, int r) -> pair<Mod, Mod> {
if(r < l) {
return {1, 0};
}
if(l == 0) {
return pref[r];
}
auto [a1, b1] = pref[l - 1];
auto [a, b] = pref[r];
return {a / a1, b - (a / a1) * b1};
};
vector<int> next(n);
next.back() = n - 1;
for(int i = n - 2; i >= 0; i--) {
auto [a, b] = vs[i];
if(a == 1 && vs[i + 1].first == 1) {
next[i] = next[i + 1];
}
else {
next[i] = i;
}
}
vector<ll> ps;
ps.push_back(vs[0].second);
for(int i = 1; i < n; i++) {
ps.push_back(ps.back() + vs[i].second);
}
auto gets = [&] (int l, int r) -> ll {
if(l == 0) {
return ps[r];
}
return ps[r] - ps[l - 1];
};
auto query = [&] (ll x, int l, int r) -> ll {
int i = l;
while(i <= r && x < 1000000007) {
if (vs[i].first > 1) {
x = max(x + vs[i].second, x * vs[i].first);
i++;
}
else {
int go = min(next[i], r);
x += gets(i, go);
i = go + 1;
}
}
x %= mod;
auto [a, b] = get(i, r);
return (a * x + b).x;
};
for(int i = 0; i < q; i++) {
ll x, l, r;
cin >> x >> l >> r;
r--;
cout << query(x, l, r) << "\n";
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
//freopen("in", "r", stdin);
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 121 122 123 124 125 126 127 128 | #include <bits/stdc++.h> using namespace std; using ll = int64_t; constexpr ll mod = 1000000007; ll euclid(ll a, ll b, ll &x, ll &y) { if (!b) return x = 1, y = 0, a; ll d = euclid(b, a % b, y, x); return y -= a/b * x, d; } struct Mod { ll x; Mod(ll xx) : x(xx) {} Mod operator+(Mod b) { return Mod((x + b.x) % mod); } Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); } Mod operator*(Mod b) { return Mod((x * b.x) % mod); } Mod operator/(Mod b) { return *this * invert(b); } Mod invert(Mod a) { ll x, y, g = euclid(a.x, mod, x, y); assert(g == 1); return Mod((x + mod) % mod); } Mod operator^(ll e) { if (!e) return Mod(1); Mod r = *this ^ (e / 2); r = r * r; return e&1 ? *this * r : r; } }; void solve() { int n, q; cin >> n >> q; vector<pair<ll, ll>> vs(n); for(auto& [a, b] : vs) { cin >> b >> a; } vector<pair<Mod, Mod>> pref; pref.push_back(vs[0]); for(int i = 1; i < n; i++) { auto [a, b] = vs[i]; if(a == 1) { pref.emplace_back(pref.back().first, pref.back().second + b); } else { pref.emplace_back(pref.back().first * a, pref.back().second * a); } } auto get = [&] (int l, int r) -> pair<Mod, Mod> { if(r < l) { return {1, 0}; } if(l == 0) { return pref[r]; } auto [a1, b1] = pref[l - 1]; auto [a, b] = pref[r]; return {a / a1, b - (a / a1) * b1}; }; vector<int> next(n); next.back() = n - 1; for(int i = n - 2; i >= 0; i--) { auto [a, b] = vs[i]; if(a == 1 && vs[i + 1].first == 1) { next[i] = next[i + 1]; } else { next[i] = i; } } vector<ll> ps; ps.push_back(vs[0].second); for(int i = 1; i < n; i++) { ps.push_back(ps.back() + vs[i].second); } auto gets = [&] (int l, int r) -> ll { if(l == 0) { return ps[r]; } return ps[r] - ps[l - 1]; }; auto query = [&] (ll x, int l, int r) -> ll { int i = l; while(i <= r && x < 1000000007) { if (vs[i].first > 1) { x = max(x + vs[i].second, x * vs[i].first); i++; } else { int go = min(next[i], r); x += gets(i, go); i = go + 1; } } x %= mod; auto [a, b] = get(i, r); return (a * x + b).x; }; for(int i = 0; i < q; i++) { ll x, l, r; cin >> x >> l >> r; r--; cout << query(x, l, r) << "\n"; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); //freopen("in", "r", stdin); solve(); } |
English