-
难得一次推麻烦点的矩阵,矩阵快速幂以后要有信心推下去,暴力推就行了
-
第一次用Markdown完整的写完了一篇题解,这数学公式可真要命
题目描述:
- 一个数列 a n {a_n} an,满足 a n = x ∗ a n − 1 + y ∗ a n − 2 a_n = x * a_{n - 1} + y * a_{n - 2} an=x∗an−1+y∗an−2,求 ∑ i = 1 n a i 3 \sum^{n}_{i = 1} {a_i^3} ∑i=1nai3 答案对998244353取模。
输入
- 第一行一个整数T,即数据组数。
- 下面T行,每行5个整数,即n,a1,a2,x,y,含义如上。
输出
- 共T行,每行1个整数,即每组数据的答案。
样例输入
3
3 0 2 0 0
3 1 2 0 1
3 1 0 0 1
样例输出
8
10
2
提示
- 对于100%的数据, 1 ≤ T ≤ 1 0 4 , 1 ≤ n ≤ 1 0 18 , 0 ≤ a 1 , a 2 , x , y ≤ 998244352 1≤T≤10^4,1≤n≤10^{18},0≤a_1,a_2,x,y≤998244352 1≤T≤104,1≤n≤1018,0≤a1,a2,x,y≤998244352
题解:
就暴力拆开三次方 a n 3 = x 3 a n − 1 3 + 3 x 2 y a n − 1 2 a n − 2 + 3 x y 2 a n − 1 a n − 2 2 + y 3 a n − 2 3 a_n^3 = x^3 a_{n-1}^3 + 3 x^2 y a_{n-1}^2 a_{n-2} + 3 x y ^ 2 a_{n - 1} a_{n - 2}^2 + y^3 a_{n-2}^3 an3=x3an−13+3x2yan−12an−2+3xy2an−1an−22+y3an−23
然后用常用推矩阵的思路直接上4阶基矩阵
b a s e = ( x 3 3 x 2 y 3 x y 2 y 3 x 2 2 x y y 2 0 x y 0 0 1 0 0 0 ) (1) base=\begin{pmatrix}x^3 & 3 x^2 y & 3 x y^2 & y^3\\x^2 & 2 x y & y^2 & 0\\x & y & 0 & 0\\1 & 0 & 0 & 0\end{pmatrix}\tag{1} base=⎝⎜⎜⎛x3x2x13x2y2xyy03xy2y200y3000⎠⎟⎟⎞(1)
即
(
a
n
3
a
n
2
a
n
−
1
a
n
a
n
−
1
2
a
n
−
1
3
)
=
(
x
3
3
x
2
y
3
x
y
2
y
3
x
2
2
x
y
y
2
0
x
y
0
0
1
0
0
0
)
(
a
n
−
1
3
a
n
−
1
2
a
n
−
2
a
n
−
1
a
n
−
2
2
a
n
−
2
3
)
(2)
\begin{pmatrix}a_n^3 \\a_n^2 a_{n-1} \\a_n a_{n-1}^2 \\a_{n-1}^3\end{pmatrix}=\begin{pmatrix}x^3 & 3 x^2 y & 3 x y^2 & y^3\\x^2 & 2 x y & y^2 & 0\\x & y & 0 & 0\\1 & 0 & 0 & 0\end{pmatrix}\begin{pmatrix}a_{n-1}^3 \\a_{n-1}^2 a_{n-2} \\a_{n-1} a_{n-2}^2 \\a_{n-2}^3\end{pmatrix}\tag{2}
⎝⎜⎜⎛an3an2an−1anan−12an−13⎠⎟⎟⎞=⎝⎜⎜⎛x3x2x13x2y2xyy03xy2y200y3000⎠⎟⎟⎞⎝⎜⎜⎛an−13an−12an−2an−1an−22an−23⎠⎟⎟⎞(2)
( a n 3 a n 2 a n − 1 a n a n − 1 2 a n − 1 3 ) = ( x 3 3 x 2 y 3 x y 2 y 3 x 2 2 x y y 2 0 x y 0 0 1 0 0 0 ) n − 2 ( a 2 3 a 2 2 a 1 a 2 a 1 2 a 1 3 ) (3) \begin{pmatrix}a_n^3 \\a_n^2 a_{n-1} \\a_n a_{n-1}^2 \\a_{n-1}^3\end{pmatrix}=\begin{pmatrix}x^3 & 3 x^2 y & 3 x y^2 & y^3\\x^2 & 2 x y & y^2 & 0\\x & y & 0 & 0\\1 & 0 & 0 & 0\end{pmatrix}^{n - 2}\begin{pmatrix}a_2^3 \\a_2^2 a_1 \\a_2 a_1^2 \\a_1^3\end{pmatrix}\tag{3} ⎝⎜⎜⎛an3an2an−1anan−12an−13⎠⎟⎟⎞=⎝⎜⎜⎛x3x2x13x2y2xyy03xy2y200y3000⎠⎟⎟⎞n−2⎝⎜⎜⎛a23a22a1a2a12a13⎠⎟⎟⎞(3)
那么这个 a n 3 a_n^3 an3 就可以顺利用矩阵快速幂推出来了
题目求的是 ∑ i = 1 n a i 3 \sum^{n}_{i = 1} {a_i^3} ∑i=1nai3,令 S n = ∑ i = 1 n a i 3 S_n = \sum^{n}_{i = 1} {a_i^3} Sn=∑i=1nai3
那么对基矩阵增加一行一列即可
b a s e = ( 1 x 3 3 x 2 y 3 x y 2 y 3 0 x 3 3 x 2 y 3 x y 2 y 3 0 x 2 2 x y y 2 0 0 x y 0 0 0 1 0 0 0 ) (4) base=\begin{pmatrix}1 & x^3 & 3 x^2 y & 3 x y^2 & y^3 \\0 & x^3 & 3 x^2 y & 3 x y^2 & y^3 \\0 & x^2 & 2 x y & y^2 & 0 \\0 & x & y & 0 & 0 \\0 & 1 & 0 & 0 & 0\end{pmatrix}\tag{4} base=⎝⎜⎜⎜⎜⎛10000x3x3x2x13x2y3x2y2xyy03xy23xy2y200y3y3000⎠⎟⎟⎟⎟⎞(4)
即
(
S
n
a
n
3
a
n
2
a
n
−
1
a
n
a
n
−
1
2
a
n
−
1
3
)
=
(
1
x
3
3
x
2
y
3
x
y
2
y
3
0
x
3
3
x
2
y
3
x
y
2
y
3
0
x
2
2
x
y
y
2
0
0
x
y
0
0
0
1
0
0
0
)
(
S
n
−
1
a
n
−
1
3
a
n
−
1
2
a
n
−
2
a
n
−
1
a
n
−
2
2
a
n
−
2
3
)
(5)
\begin{pmatrix}{S}_n \\a_n^3 \\a_n^2 a_{n-1} \\a_n a_{n-1}^2 \\a_{n-1}^3\end{pmatrix}= \begin{pmatrix}1 & x^3 & 3 x^2 y & 3 x y^2 & y^3 \\0 & x^3 & 3 x^2 y & 3 x y^2 & y^3\\0 & x^2 & 2 x y & y^2 & 0\\0 & x & y & 0 & 0\\0 & 1 & 0 & 0 & 0\end{pmatrix}\begin{pmatrix}S_{n-1} \\a_{n-1}^3 \\a_{n-1}^2 a_{n-2} \\a_{n-1} a_{n-2}^2 \\a_{n-2}^3\end{pmatrix}\tag{5}
⎝⎜⎜⎜⎜⎛Snan3an2an−1anan−12an−13⎠⎟⎟⎟⎟⎞=⎝⎜⎜⎜⎜⎛10000x3x3x2x13x2y3x2y2xyy03xy23xy2y200y3y3000⎠⎟⎟⎟⎟⎞⎝⎜⎜⎜⎜⎛Sn−1an−13an−12an−2an−1an−22an−23⎠⎟⎟⎟⎟⎞(5)
( S n a n 3 a n 2 a n − 1 a n a n − 1 2 a n − 1 3 ) = ( 1 x 3 3 x 2 y 3 x y 2 y 3 0 x 3 3 x 2 y 3 x y 2 y 3 0 x 2 2 x y y 2 0 0 x y 0 0 0 1 0 0 0 ) n − 2 ( S 2 a 2 3 a 2 2 a 1 a 2 a 1 2 a 1 3 ) (6) \begin{pmatrix}{S}_n \\a_n^3 \\a_n^2 a_{n-1} \\a_n a_{n-1}^2 \\a_{n-1}^3\end{pmatrix}= \begin{pmatrix}1 & x^3 & 3 x^2 y & 3 x y^2 & y^3 \\0 & x^3 & 3 x^2 y & 3 x y^2 & y^3\\0 & x^2 & 2 x y & y^2 & 0\\0 & x & y & 0 & 0\\0 & 1 & 0 & 0 & 0\end{pmatrix}^{n - 2}\begin{pmatrix}S_2 \\a_2^3 \\a_2^2 a_1 \\a_2 a_1^2 \\a_1^3\end{pmatrix}\tag{6} ⎝⎜⎜⎜⎜⎛Snan3an2an−1anan−12an−13⎠⎟⎟⎟⎟⎞=⎝⎜⎜⎜⎜⎛10000x3x3x2x13x2y3x2y2xyy03xy23xy2y200y3y3000⎠⎟⎟⎟⎟⎞n−2⎝⎜⎜⎜⎜⎛S2a23a22a1a2a12a13⎠⎟⎟⎟⎟⎞(6)
#pragma GCC optimize(3, "Ofast", "inline")
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
#define REP(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)
#define DREP(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)
#define EREP(i, a) for(register int i = (be[a]); i != -1; i = nxt[i])
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mem(a, b) memset((a), b, sizeof(a))
template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
template <class T>
T read(T sum = 0, T fg = 0)
{
char c = getchar();
while(c < '0' || c > '9') { fg |= c == '-'; c = getchar(); }
while(c >= '0' && c <= '9') { sum = sum * 10 + c - '0'; c = getchar(); }
return fg ? -sum : sum;
}
const int inf = 1e9;
const LL INF = 1e17;
const int Size = 1000010;
const LL mod = 998244353;
struct Matrix
{
LL matrix[6][6];
int lenx, leny;
Matrix()
{
lenx = 5; leny = 5;
mem(matrix, 0);
}
void base()
{
REP(i, 1, 5) matrix[i][i] = 1;
}
friend Matrix operator * (Matrix a, Matrix b)
{
Matrix res;
res.lenx = a.lenx; res.leny = b.leny;
REP(i, 1, res.lenx) REP(j, 1, res.leny) REP(k, 1, a.leny)
{
(res.matrix[i][j] += a.matrix[i][k] * b.matrix[k][j] % mod) %= mod;
}
return res;
}
};
Matrix qpow(Matrix a, LL N)
{
Matrix ans; ans.base();
while(N)
{
if(N & 1LL) ans = ans * a;
a = a * a;
N >>= 1LL;
}
return ans;
}
LL calc(LL x, int k)
{
LL ans = 1LL;
while(k--) ans = ans * x % mod;
return ans % mod;
}
void solve()
{
LL n = read<LL>();
LL a1 = read<LL>() % mod, a2 = read<LL>() % mod;
LL x = read<LL>() % mod, y = read<LL>() % mod;
if(n == 1)
{
printf("%lld\n", calc(a1, 3));
return;
}
if(n == 2)
{
printf("%lld\n", (calc(a1, 3) + calc(a2, 3)) % mod);
return;
}
Matrix a, b;
a.matrix[1][1] = 1;
a.matrix[1][2] = calc(x, 3);
a.matrix[1][3] = 3 * calc(x, 2) % mod * y % mod;
a.matrix[1][4] = 3 * x % mod * calc(y, 2) % mod;
a.matrix[1][5] = calc(y, 3);
a.matrix[2][1] = 0;
a.matrix[2][2] = calc(x, 3);
a.matrix[2][3] = 3 * calc(x, 2) % mod * y % mod;
a.matrix[2][4] = 3 * x % mod * calc(y, 2) % mod;
a.matrix[2][5] = calc(y, 3);
a.matrix[3][1] = 0;
a.matrix[3][2] = calc(x, 2);
a.matrix[3][3] = 2 * x % mod * y % mod;
a.matrix[3][4] = calc(y, 2);
a.matrix[3][5] = 0;
a.matrix[4][1] = 0;
a.matrix[4][2] = x;
a.matrix[4][3] = y;
a.matrix[4][4] = 0;
a.matrix[4][5] = 0;
a.matrix[5][1] = 0;
a.matrix[5][2] = 1;
a.matrix[5][3] = 0;
a.matrix[5][4] = 0;
a.matrix[5][5] = 0;
Matrix ans = qpow(a, n - 2);
b.lenx = 5; b.leny = 1;
b.matrix[1][1] = (calc(a1, 3) + calc(a2, 3)) % mod;
b.matrix[2][1] = calc(a2, 3);
b.matrix[3][1] = calc(a2, 2) * a1 % mod;
b.matrix[4][1] = a2 * calc(a1, 2) % mod;
b.matrix[5][1] = calc(a1, 3);
ans = ans * b;
printf("%lld\n", ans.matrix[1][1]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
freopen("output.out", "w", stdout);
#endif
int Case = read<int>();
while(Case--) solve();
return 0;
}