1 条题解
-
0
自动搬运
来自洛谷,原作者为

Kevin_Zhen
不再回来搬运于
2025-08-24 22:07:55,当前版本为作者最后更新于2021-04-28 19:47:44,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目大意
一个数列 ,已知 、 两项及两个系数 和 ,数列 满足递推式 ,求 。
解题思路
题目相比于普通的矩阵加速,最大的难点在于所求答案为各项平方和。我们需要通过 和 求解 ,即 。根据构造矩阵时,要将求解所求答案所需元素放入构造矩阵中的思路,我们不妨直接将 放入构造矩阵中,在接下来的做题过程中也应更多关注于 的求解,而非 ( 并未用到)。
先确定矩阵转移方程。假设我们当前要由矩阵 转移到矩阵 吧。
首先要包括所求内容,当前两矩阵分别为: 和 。
求解 需要用到 ,所以矩阵 变为 ,相应地,矩阵 变为 。
由 得,矩阵 变为 。此时两矩阵分别为:$\begin{bmatrix}S_i\\x^2{a_i}^2+y^2{a_{i-1}}^2+2xya_ia_{i-1}\end{bmatrix}$ 和 。
从矩阵 中可以看出,要想求得矩阵 ,矩阵 中还需放入 和 两项。将这两项放入矩阵 ,两矩阵相应变为:$\begin{bmatrix}S_i\\x^2{a_i}^2+y^2{a_{i-1}}^2+2xya_ia_{i-1}\\{a_i}^2\\a_{i+1}a_i\end{bmatrix}$ 和 $\begin{bmatrix}S_{i-1}\\{a_i}^2\\{a_{i-1}}^2\\a_ia_{i-1}\end{bmatrix}$。
最后再次用 消去矩阵 中的 ,得到最终的两矩阵:
$\begin{bmatrix}S_i\\x^2{a_i}^2+y^2{a_{i-1}}^2+2xya_ia_{i-1}\\{a_i}^2\\x{a_i}^2+ya_ia_{i-1}\end{bmatrix}$ 和 $\begin{bmatrix}S_{i-1}\\{a_i}^2\\{a_{i-1}}^2\\a_ia_{i-1}\end{bmatrix}$。
此时矩阵 已经完全可以由矩阵 转移得到了。具体的转移方式是将矩阵 乘上一个由对应系数构成的矩阵。得到最终的矩阵转移方程为:
$\begin{bmatrix}S_i\\x^2{a_i}^2+y^2{a_{i-1}}^2+2xya_ia_{i-1}\\{a_i}^2\\x{a_i}^2+ya_ia_{i-1}\end{bmatrix}=\begin{bmatrix}1\ 1\ 0\ 0\\0\ x^2\ y^2\ 2xy\\0\ 1\ 0\ 0\\0\ x\ 0\ y\end{bmatrix}\times\begin{bmatrix}S_{i-1}\\{a_i}^2\\{a_{i-1}}^2\\a_ia_{i-1}\end{bmatrix}$。时间复杂度为 ,其中 为矩阵的边长。注意此题 ,,时限为 ,此时矩阵的边长已经不能当作一个常数忽略不计了。估算得 时执行次数约为 ,边长大于 的矩阵是无法接受的。
AC CODE
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef unsigned long long ull; const int Mod = 1e9 + 7; struct Matrix { ull a[15][15]; int n, m; ull* operator [](int x) { return a[x]; } void clear() { n = 0, m = 0, memset(a, 0, sizeof(a)); } }; Matrix operator *(Matrix &x, Matrix &y) { Matrix z; z.clear(); z.n = x.n, z.m = y.m; for (int i = 1; i <= x.n; ++i) { for (int j = 1; j <= x.m; ++j) { for (int k = 1; k <= y.m; ++k) z[i][k] = (z[i][k] + x[i][j] * y[j][k]) % Mod; } } return z; } int T; ull n, a1, a2, x, y; Matrix a, b, ans; Matrix qpow(Matrix base, ull p) { Matrix res = base; --p; while (p) { if (p & 1) res = res * base; base = base * base; p >>= 1; } return res; } int main() { scanf("%d", &T); while (T--) { a.clear(); b.clear(); ans.clear(); scanf("%llu%llu%llu%llu%llu", &n, &a1, &a2, &x, &y); a1 %= Mod, a2 %= Mod, x %= Mod, y %= Mod; if (n == 1) { printf("%llu\n", a1 * a1 % Mod); continue; } a.n = a.m = 4; b.n = 4, b.m = 1; a[1][1] = a[1][2] = a[3][2] = 1; a[2][2] = x * x % Mod; a[2][3] = y * y % Mod; a[2][4] = 2 * x * y % Mod; a[4][2] = x; a[4][4] = y; b[1][1] = b[3][1] = a1 * a1 % Mod; b[2][1] = a2 * a2 % Mod; b[4][1] = a2 * a1 % Mod; ans = qpow(a, n - 1); ans = ans * b; printf("%llu\n", ans[1][1]); } return 0; }感谢观赏!
- 1
信息
- ID
- 4121
- 时间
- 1500ms
- 内存
- 16MiB
- 难度
- 5
- 标签
- (无)
- 递交数
- 0
- 已通过
- 0
- 上传者