#include <bits/stdc++.h>
#define ll long long
#define pi std::pair<int, int>
#define pll std::pair<ll, ll>
#define vi std::vector<int>
#define vll std::vector<ll>
#define vpi std::vector<pi>
#define vpll std::vector<pll>
#define si std::set<int>
// logika: moge przejsc max 20 razy, by zwiekszyc liczbe zolnierzy tak, by oplacalo sie tylko mnozyc
// z wyjatkiem ze musze jakos obsluzyc zapytania typu (a, 1)
// moge dodac jakis balans a potem robic po tym autostrade, tzn. miec fixed sume, oraz miec tablice
// na bazie ktorej szybko przemnoze?
ll x = 1, y = 0, last_y; // przy kazdym gcd na start x = 1 i y = 0; inaczej sie rozjezdza
ll gcd(ll a, ll b)
{
if (b == 0)
return a;
ll _gcd = gcd(b, a % b);
last_y = y;
y = x - a / b * last_y;
x = last_y;
return _gcd;
}
void solve() {
ll n, q, mod = 1e9 + 7;
std::cin >> n >> q;
vll multtab(n+1), sumtab(n+1), jump(n+1), prefsum(n+1);
multtab[0] = 1;
vpll v(n+1);
for(int i = 1; i <= n; i++) {
std::cin >> v[i].first >> v[i].second;
sumtab[i] = sumtab[i-1];
if(v[i].second == 1)
sumtab[i] += v[i].first;
else
sumtab[i] *= v[i].second;
sumtab[i] %= mod;
prefsum[i] = prefsum[i-1] + v[i].first;
multtab[i] = multtab[i-1] * v[i].second;
multtab[i] %= mod;
}
ll last = n+1;
for(int i = n; i >= 0; i--) {
jump[i] = last;
if(v[i].second != 1)
last = i;
}
ll ox, l, r;
for(int i = 0; i < q; i++) {
std::cin >> ox >> l >> r;
ll nl = l + 1, nx = ox;
while(nl <= r && nx < mod) {// idk chyba tak
if(v[nl].second == 1) {
nx += prefsum[std::min(jump[nl]-1, r)] - prefsum[nl-1];
nl = std::min(jump[nl]-1, r) + 1;
}
else {
nx = std::max(nx + v[nl].first, nx * v[nl].second);
nl++;
}
}
nx %= mod;
nx -= sumtab[nl-1];
if(nx < 0)
nx += mod;
nx *= multtab[r];
nx %= mod;
x = 1, y = 0;
gcd(multtab[nl-1], mod);
ll inv = (x % mod + mod) % mod;
nx *= inv;
nx %= mod;
nx += sumtab[r];
nx %= mod;
std::cout << nx << '\n';
}
}
int main() {
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
int t = 1;
//std::cin >> t;
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 | #include <bits/stdc++.h> #define ll long long #define pi std::pair<int, int> #define pll std::pair<ll, ll> #define vi std::vector<int> #define vll std::vector<ll> #define vpi std::vector<pi> #define vpll std::vector<pll> #define si std::set<int> // logika: moge przejsc max 20 razy, by zwiekszyc liczbe zolnierzy tak, by oplacalo sie tylko mnozyc // z wyjatkiem ze musze jakos obsluzyc zapytania typu (a, 1) // moge dodac jakis balans a potem robic po tym autostrade, tzn. miec fixed sume, oraz miec tablice // na bazie ktorej szybko przemnoze? ll x = 1, y = 0, last_y; // przy kazdym gcd na start x = 1 i y = 0; inaczej sie rozjezdza ll gcd(ll a, ll b) { if (b == 0) return a; ll _gcd = gcd(b, a % b); last_y = y; y = x - a / b * last_y; x = last_y; return _gcd; } void solve() { ll n, q, mod = 1e9 + 7; std::cin >> n >> q; vll multtab(n+1), sumtab(n+1), jump(n+1), prefsum(n+1); multtab[0] = 1; vpll v(n+1); for(int i = 1; i <= n; i++) { std::cin >> v[i].first >> v[i].second; sumtab[i] = sumtab[i-1]; if(v[i].second == 1) sumtab[i] += v[i].first; else sumtab[i] *= v[i].second; sumtab[i] %= mod; prefsum[i] = prefsum[i-1] + v[i].first; multtab[i] = multtab[i-1] * v[i].second; multtab[i] %= mod; } ll last = n+1; for(int i = n; i >= 0; i--) { jump[i] = last; if(v[i].second != 1) last = i; } ll ox, l, r; for(int i = 0; i < q; i++) { std::cin >> ox >> l >> r; ll nl = l + 1, nx = ox; while(nl <= r && nx < mod) {// idk chyba tak if(v[nl].second == 1) { nx += prefsum[std::min(jump[nl]-1, r)] - prefsum[nl-1]; nl = std::min(jump[nl]-1, r) + 1; } else { nx = std::max(nx + v[nl].first, nx * v[nl].second); nl++; } } nx %= mod; nx -= sumtab[nl-1]; if(nx < 0) nx += mod; nx *= multtab[r]; nx %= mod; x = 1, y = 0; gcd(multtab[nl-1], mod); ll inv = (x % mod + mod) % mod; nx *= inv; nx %= mod; nx += sumtab[r]; nx %= mod; std::cout << nx << '\n'; } } int main() { std::ios_base::sync_with_stdio(0); std::cin.tie(0); int t = 1; //std::cin >> t; while(t--) { solve(); } } |
English