【矩阵乘法入门】 http://blog.csdn.net/mig_davidli/article/details/8601304;
这算是我个人的学习笔记吧,再简单的看了【矩阵乘法入门以后】,去百度文库上查了下矩阵乘法的应用,挺不错的。
首先练习了一下 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;
- }