我正在研究一个问题,我应该找到nth
一个4x4
矩阵的幂,它n
可以和我一样大10^15
,因为答案中的值可能非常大,我可以使用modulo 10^9+7
。给定矩阵是-
2 1 -2 -1
A= 1 0 0 0
0 1 0 0
0 0 1 0
我为此目的编写了一个代码,但它的运行时间超过了预期的时间。因此,请任何人帮助我降低时间复杂度。
#define FOR(k,a,b) for(typeof(a) k=(a); k < (b); ++k)
typedef long long ll;
#define dim 4
struct matrix {
long long a[dim][dim];
};
#define MOD 1000000007
matrix mul(matrix x, matrix y)
{
matrix res;
FOR(a, 0, dim) FOR(b, 0, dim) res.a[a][b] = 0;
FOR(a, 0, dim) FOR(b, 0, dim) FOR(c, 0, dim) {
ll temp = x.a[a][b] * y.a[b][c];
if (temp <= -MOD || temp >= MOD)
temp %= MOD;
res.a[a][c] += temp;
if (res.a[a][c] <= -MOD || res.a[a][c] >= MOD)
res.a[a][c] %= MOD;
}
return res;
}
matrix power(matrix m, ll n)
{
if (n == 1)
return m;
matrix u = mul(m, m);
u = power(u, n / 2);
if (n & 1)
u = mul(u, m);
return u;
}
matrix M, RP;
int main()
{
FOR(a, 0, dim) FOR(b, 0, dim) M.a[a][b] = 0;
M.a[0][0] = 2;
M.a[0][1] = 1;
M.a[0][2] = -2;
M.a[0][3] = -1;
M.a[1][0] = 1;
M.a[2][1] = 1;
M.a[3][2] = 1;
int nt;
scanf("%d", &nt);
while (nt--) {
ll n;
scanf("%lld", &n);
RP = power(M, n);
FOR(a, 0, dim)
FOR(b, 0, dim)
printf("%lld\n", RP.a[a][b]);
}
return 0;
}