【矩阵乘法入门】 http://blog.csdn.net/mig_davidli/article/details/8601304;
【算法学习 矩阵乘法及其应用_百度文库.】 http://wenku.baidu.com/view/4bbbf1c38bd63186bcebbc80.html;
这算是我个人的学习笔记吧,再简单的看了【矩阵乘法入门以后】,去百度文库上查了下矩阵乘法的应用,挺不错的。
首先练习了一下 poj 3233 。 http://poj.org/problem?id=3233;
这道题的矩阵求和 应用了两次二分,很灵活。
题意 : S = A^1 + A^2 + A^3 + ... + A^k;
因为 A^4 = A^A^A^A =( A^2 ) ^2; 所以可以应用二分求解 A^x;
又因为 A^1 + A^2 + A^3 + A^4 + A^5 + A^6 +A^7 = (A^1 + A^2 + A^3) + A^4+A^4*(A^1 + A^2 + A^3);
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 36
int n, k, m;
struct Mar
{
int map[maxn][maxn];
void unit() ///单位矩阵
{
for(int i=0;i<maxn;i++)
map[i][i] = 1;
}
void zero() ///零矩阵
{
memset(map,0,sizeof(map));
}
}x;
Mar operator +(const Mar &a,const Mar &b)
{
Mar tmp;
tmp.zero();
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++){
tmp.map[i][j] =a.map[i][j] + b.map[i][j];
if(tmp.map[i][j]>=m) tmp.map[i][j]%=m;
}
return tmp;
}
Mar operator *(const Mar &a,const Mar &b)
{
Mar tmp;
tmp.zero();
int i,j,k;
for(k=0;k<n;k++)
for(i=0;i<n;i++)
/// if(a.map[i][k])
for(j=0;j<n;j++){
tmp.map[i][j] += a.map[i][k] * b.map[k][j];
if(tmp.map[i][j]>=m)
tmp.map[i][j]%=m;
}
return tmp;
}
Mar operator ^ (Mar x,int n)
{
Mar tmp;
tmp.zero();
tmp.unit();
while(n){
if(n%2==1) tmp = tmp *x;
n/=2;
x = x*x;
}
return tmp;
}
Mar sum(int n)
{
if(n==1) return x;
else {
Mar tmp = sum(n/2);
if(n%2==1){
Mar tmp2 = x ^ ((n/2)+1);
return tmp + tmp2 + tmp*tmp2;
}
else {
Mar tmp2 = x ^ (n/2);
return tmp + tmp * tmp2;
}
}
}
int main()
{
while(~scanf("%d%d%d",&n,&k,&m))
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++){
scanf("%d",&x.map[i][j]);
x.map[i][j]%=m;
}
Mar y = sum(k);
for(i=0;i<n;i++)
for(j=0;j<n;j++){
printf("%d%c",y.map[i][j],j==n-1?'\n':' ');
}
break;
}
return 0;
}