题目来源:http://poj.org/problem?id=3233
题目来源:http://acm.nyist.net/JudgeOnline/problem.php?pid=299
本题用二分,快速幂来求;
A+A^2+A^3+A^4+·······A^k;
当k是奇数时, sum = (A + A^2+······A^(k/2)) + A^(k/2+1)[A + A^2 + ····A^(K/2)] + A^k;
当k是偶数的时候,sum = (A + ·······A^(k/2)) + A^(k/2)[A + A^2 + ····A^(k/2)];
因此可以利用二分的性质求累加和,至于A^k当然是快速幂了。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 35;
struct Matrix
{
int iMatrix[MAXN][MAXN];
};
int n, iMod;
Matrix iPer, A;
void Inite_Matrix()
{
int i, j;
for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
scanf("%d", &A.iMatrix[i][j]);
A.iMatrix[i][j] %= iMod;
iPer.iMatrix[i][j] = (i == j);//单位矩阵
}
}
}
Matrix Multi_Matrix(Matrix a, Matrix b)//两个矩阵相乘
{
int i, j, k;
Matrix c;
for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
c.iMatrix[i][j] = 0;
for(k = 0; k < n; ++k)
c.iMatrix[i][j] += a.iMatrix[i][k] * b.iMatrix[k][j];
c.iMatrix[i][j] %= iMod;
}
}
return c;
}
Matrix Add_Matrix(Matrix a, Matrix b)//相加
{
int i, j;
Matrix c;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
c.iMatrix[i][j] = (a.iMatrix[i][j] + b.iMatrix[i][j])%iMod;
return c;
}
Matrix Quick_Matrix_Power(int k)//矩阵快速幂
{
Matrix c, tmp;
c = iPer;
tmp = A;
while(k)
{
if(k&1)
{
c = Multi_Matrix(c, tmp);
k--;
}
else
{
k >>= 1;
tmp = Multi_Matrix(tmp, tmp);
}
}
return c;
}
Matrix Binary_Search_MatrixSum(int k)//求前k项的和
{
if(k == 1)
return A;
Matrix tmp, b;
tmp = Binary_Search_MatrixSum(k>>1);
if(k&1)
{
b = Quick_Matrix_Power((k>>1) + 1);
tmp = Add_Matrix(tmp, Multi_Matrix(tmp, b));
tmp = Add_Matrix(tmp, b);
}
else
{
b = Quick_Matrix_Power(k>>1);
tmp = Add_Matrix(tmp, Multi_Matrix(tmp, b));
}
return tmp;
}
int main()
{
int i, j, k;
Matrix res;
while(~scanf("%d %d %d", &n, &k, &iMod))
{
Inite_Matrix();
res = Binary_Search_MatrixSum(k);
for(i = 0; i < n; ++i)
{
for(j = 0; j < n-1; ++j)
printf("%d ", res.iMatrix[i][j]);
printf("%d\n", res.iMatrix[i][j]);
}
}
return 0;
}