题意:
给矩阵A,求Σi=(1,k) Ai
SOL:
虽然可以快速幂,然而还是会炸,那么我们就优化一下。。。
若k是偶数,则S=(1+1^(k/2))(A^1+A^2+……+A^(k/2))
若k是奇数,则S=(1+1^(k/2))(A^1+A^2+……+A^(k/2))+A^k
像是快速幂套快速幂。。。。复杂度。。一个log还是两个log呢。。
Code:
#include <iostream>
#include <cstdio>
using namespace std;
int n, m;
struct Matrix
{
int x[31][31];
};
void matrixPrint(Matrix mat)
{
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (j > 0) printf(" ");
printf("%d", mat.x[i][j]);
}
printf("\n");
}
}
Matrix matrixMultiply(Matrix a, Matrix b)
{
Matrix ret;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
ret.x[i][j] = 0;
for (int t = 0; t < n; ++t)
{
ret.x[i][j] += a.x[i][t] * b.x[t][j];
if (ret.x[i][j] >= m) ret.x[i][j] %= m;
}
}
}
return ret;
}
Matrix matrixPow(Matrix mat, int p)
{
Matrix ret;
Matrix tmp = mat;
for (int i = 0; i < n; ++i)
{
ret.x[i][i] = 1;
for (int j = i + 1; j < n; ++j)
{
ret.x[i][j] = 0;
ret.x[j][i] = 0;
}
}
while (p > 0)
{
if (p & 1) ret = matrixMultiply(ret, tmp);
p >>= 1;
tmp = matrixMultiply(tmp, tmp);
}
return ret;
}
Matrix matrixSummary(Matrix mat, int k)
{
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (mat.x[i][j] >= m) mat.x[i][j] %= m;
}
}
if (k == 1) return mat;
Matrix M1 = matrixPow(mat, k / 2);
for (int i = 0; i < n; ++i)
{
M1.x[i][i] += 1;
}
Matrix M2 = matrixSummary(mat, k / 2);
Matrix ret = matrixMultiply(M1, M2);
if (k & 1)
{
Matrix tmp = matrixPow(mat, k);
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
ret.x[i][j] += tmp.x[i][j];
if (ret.x[i][j] >= m) ret.x[i][j] %= m;
}
}
}
return ret;
}
int main()
{
Matrix mat;
int k;
scanf("%d%d%d", &n, &k, &m);
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
scanf("%d", &mat.x[i][j]);
}
}
Matrix ret = matrixSummary(mat, k);
matrixPrint(ret);
return 0;
}
貌似还有更牛逼的。。。到时候再学下好了。。。