题解:P16822 [蓝桥杯 2026 国 Python B] 零段积分
世界机器还是太厉害了,来点唐唐做法。
设
容易发现
其中
设
上式显然只跟
考虑
套路地拆出来最后一项,容易得到递推式:
递推的同时算出
进一步优化,考虑矩阵快速幂加速。容易想到要把
于是设
将
简单推一下矩阵。初始向量为
转移矩阵为
直接计算
:::success[主要代码]
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
using ui = unsigned int;
using ull = unsigned long long;
using u128 = unsigned __int128;
using ld = long double;
using pii = pair<int, int>;
const int mod = 1e9 + 7;
template<typename T> T lowbit(T x) { return x & -x; }
template<typename T> void chkMin(T &x, T y) { x = y < x ? y : x; }
template<typename T> void chkMax(T &x, T y) { x = x < y ? y : x; }
template<typename T> T add(T x, T y) { return (x += y) >= mod ? x - mod : x; }
template<typename T> T sub(T x, T y) { return (x -= y) < 0 ? x + mod : x; }
template<typename T> void cadd(T &x, T y) { (x += y) >= mod ? (x -= mod) : x; }
template<typename T> void csub(T &x, T y) { (x -= y) < 0 ? (x += mod) : x; }
int n, p, q;
template<int N, int M>
struct Matrix {
array<array<int, M>, N> a;
Matrix() {
for (int i = 0; i < N; ++i) a[i].fill(0);
}
int &operator()(int i, int j) {
return a[i][j];
}
int operator()(int i, int j) const {
return a[i][j];
}
template<int P>
friend Matrix<N, P> operator*(const Matrix<N, M> &lhs, const Matrix<M, P> &rhs) {
Matrix<N, P> res;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < P; ++j) {
int s = 0;
for (int k = 0; k < M; ++k) cadd<int>(s, (ull)lhs(i, k) * rhs(k, j) % mod);
res(i, j) = s;
}
}
return res;
}
};
template<int N>
Matrix<N, N> idMat() {
Matrix<N, N> res;
for (int i = 0; i < N; ++i) res(i, i) = 1;
return res;
}
template<int N>
Matrix<N, N> qpow(Matrix<N, N> a, int b) {
Matrix<N, N> res = idMat<N>();
for (; b; b >>= 1) {
if (b & 1) res = res * a;
a = a * a;
}
return res;
}
int qpow(int a, int b) {
int res = 1;
for (; b; b >>= 1) {
if (b & 1) res = (ll)res * a % mod;
a = (ll)a * a % mod;
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> p >> q;
int x = (ull)p * qpow(q, mod - 2) % mod, y = sub(1, x);
Matrix<5, 1> V;
V(0, 0) = V(1, 0) = V(3, 0) = V(4, 0) = (ull)x * y % mod * y % mod;
V(2, 0) = (ull)x * x % mod;
Matrix<5, 5> T;
T(0, 0) = T(0, 1) = T(1, 1) = T(3, 0) = T(3, 1) = T(4, 0) = T(4, 1) = y;
T(0, 2) = T(1, 2) = T(3, 2) = T(4, 2) = (ull)y * y % mod;
T(2, 2) = x;
T(3, 3) = T(4, 3) = T(4, 4) = 1;
cout << (n < 3 ? 0 : (qpow(T, n - 3) * V)(4, 0));
return 0;
}
:::