#include <bitset>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
int N, Q;
const int mod = 1000 * 1000 * 1000 + 7;
const int r = 1 << 19;
const int maxN = 5e5 + 10;
struct Mat
{
long long t00, t01, t10, t11;
Mat(int a = 0, int b = 1) : t00(1), t01(a), t10(0), t11(b) {}
Mat const operator*(Mat const &o)
{
Mat res(0, 0);
res.t00 = (t00 * o.t00 + t01 * o.t10) % mod;
res.t01 = (t00 * o.t01 + t01 * o.t11) % mod;
res.t10 = (t10 * o.t00 + t11 * o.t10) % mod;
res.t11 = (t10 * o.t01 + t11 * o.t11) % mod;
return res;
}
void print(const char *suffix = "")
{
printf("(%lld %lld)(%lld %lld)%s", t00, t01, t10, t11, suffix);
}
};
Mat t[2 * r];
int A[maxN];
int B[maxN];
long long sumA[maxN];
int nextB[maxN];
Mat get(int qa, int qb, int x = 1, int ta = 0, int tb = r - 1)
{
Mat res;
if (qa > qb)
return res;
if (qa <= ta && tb <= qb)
return t[x];
int avg = (ta + tb) / 2;
if (qa <= avg)
res = res * get(qa, qb, x * 2, ta, avg);
if (avg < qb)
res = res * get(qa, qb, x * 2 + 1, avg + 1, tb);
return res;
}
long long get_sumA(int l, int r)
{
return l ? sumA[r] - sumA[l - 1] : sumA[r];
}
int ans(long long X0, int L, int R)
{
int pos = L;
int overflow = 0;
while (!overflow && pos < R)
{
// case 1: B > 1, calculate overflow
if (B[pos] > 1)
{
long long mult = B[pos] * X0;
long long add = X0 + A[pos];
X0 = max(mult, add);
if (X0 > mod)
{
overflow = 1;
X0 %= mod;
}
pos++;
continue;
}
// case 2 - skip to next B > 1
int skipto = min(nextB[pos], R);
X0 += get_sumA(pos, skipto - 1);
pos = skipto;
if (X0 > mod)
{
overflow = 1;
pos++;
}
}
Mat skip = get(pos, R - 1);
return (X0 * skip.t11 + skip.t01) % mod;
}
int main()
{
scanf("%d%d", &N, &Q);
for (int i = 0; i < N; ++i)
{
scanf("%d%d", A + i, B + i);
t[i + r] = Mat(B[i] > 1 ? 0 : A[i], max(B[i], 1));
sumA[i] = A[i] + (i ? sumA[i - 1] : 0);
}
nextB[N] = maxN;
for (int i = N - 1; i >= 0; i--)
{
nextB[i] = B[i] > 1 ? i : nextB[i + 1];
}
for (int i = r - 1; i; --i)
t[i] = t[2 * i] * t[2 * i + 1];
for (int x, r, l, i = 0; i < Q; ++i)
{
scanf("%d%d%d", &x, &l, &r);
printf("%d\n", ans(x, l, r));
}
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 | #include <bitset> #include <vector> #include <cstdio> #include <algorithm> using namespace std; int N, Q; const int mod = 1000 * 1000 * 1000 + 7; const int r = 1 << 19; const int maxN = 5e5 + 10; struct Mat { long long t00, t01, t10, t11; Mat(int a = 0, int b = 1) : t00(1), t01(a), t10(0), t11(b) {} Mat const operator*(Mat const &o) { Mat res(0, 0); res.t00 = (t00 * o.t00 + t01 * o.t10) % mod; res.t01 = (t00 * o.t01 + t01 * o.t11) % mod; res.t10 = (t10 * o.t00 + t11 * o.t10) % mod; res.t11 = (t10 * o.t01 + t11 * o.t11) % mod; return res; } void print(const char *suffix = "") { printf("(%lld %lld)(%lld %lld)%s", t00, t01, t10, t11, suffix); } }; Mat t[2 * r]; int A[maxN]; int B[maxN]; long long sumA[maxN]; int nextB[maxN]; Mat get(int qa, int qb, int x = 1, int ta = 0, int tb = r - 1) { Mat res; if (qa > qb) return res; if (qa <= ta && tb <= qb) return t[x]; int avg = (ta + tb) / 2; if (qa <= avg) res = res * get(qa, qb, x * 2, ta, avg); if (avg < qb) res = res * get(qa, qb, x * 2 + 1, avg + 1, tb); return res; } long long get_sumA(int l, int r) { return l ? sumA[r] - sumA[l - 1] : sumA[r]; } int ans(long long X0, int L, int R) { int pos = L; int overflow = 0; while (!overflow && pos < R) { // case 1: B > 1, calculate overflow if (B[pos] > 1) { long long mult = B[pos] * X0; long long add = X0 + A[pos]; X0 = max(mult, add); if (X0 > mod) { overflow = 1; X0 %= mod; } pos++; continue; } // case 2 - skip to next B > 1 int skipto = min(nextB[pos], R); X0 += get_sumA(pos, skipto - 1); pos = skipto; if (X0 > mod) { overflow = 1; pos++; } } Mat skip = get(pos, R - 1); return (X0 * skip.t11 + skip.t01) % mod; } int main() { scanf("%d%d", &N, &Q); for (int i = 0; i < N; ++i) { scanf("%d%d", A + i, B + i); t[i + r] = Mat(B[i] > 1 ? 0 : A[i], max(B[i], 1)); sumA[i] = A[i] + (i ? sumA[i - 1] : 0); } nextB[N] = maxN; for (int i = N - 1; i >= 0; i--) { nextB[i] = B[i] > 1 ? i : nextB[i + 1]; } for (int i = r - 1; i; --i) t[i] = t[2 * i] * t[2 * i + 1]; for (int x, r, l, i = 0; i < Q; ++i) { scanf("%d%d%d", &x, &l, &r); printf("%d\n", ans(x, l, r)); } return 0; } |
English