题意:给定n*n的矩阵A,整数k,mod值为m。求S=A+A^2+...+A^k。
题解:两种方法
1.矩阵构造:重新构造一个矩阵使得过程变为矩阵连乘。
2.二分:通过二分递归求解。
A+A^2+A^3+A^4+A^5+A^6=A+A^2+A^3+A^3*(A+A^2+A^3),A+A^2+A^3=A+A^2+A^2*(A)
代码:
1.矩阵构造
#include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm> #include <iostream> using namespace std; #define LL __int64 int n,mod; struct matrix{ int f[61][61]; }; matrix mul(matrix a,matrix b) { matrix c; int i,j,k; memset(c.f,0,sizeof(c.f)); for(k=0;k<n;k++) { for(i=0;i<n;i++) { if(!a.f[i][k])continue; for(j=0;j<n;j++) { if(!b.f[k][j])continue; c.f[i][j]=(c.f[i][j]+a.f[i][k]*b.f[k][j])%mod; } } } return c; } matrix pow_mod(matrix a,int b) { matrix s; memset(s.f,0,sizeof(s.f)); for(int i=0;i<n;i++) s.f[i][i]=1; while(b) { if(b&1) s=mul(s,a); a=mul(a,a); b=b>>1; } return s; } int main() { int m; while(cin>>n>>m>>mod) { int i,j,k; matrix e,g;; memset(g.f,0,sizeof(g.f)); memset(e.f,0,sizeof(e.f)); for(i=0;i<n;i++) for(j=0;j<n;j++) { cin>>e.f[i][j+n]; g.f[i+n][j+n]=e.f[i][j+n]; } for(i=0;i<n;i++) g.f[i][i]=g.f[i+n][i]=1; n=n*2; g=pow_mod(g,m); e=mul(e,g); for(i=0;i<n/2;i++) { cout<<e.f[i][0]; for(j=1;j<n/2;j++) cout<<" "<<e.f[i][j]; cout<<endl; } } return 0; } /* s[k]=A+A^2+...+A^k 矩阵: |s[0] A|*|I O|^k=|s[k] A^(k+1)| (I为单位矩阵,O为0矩阵,A为输入的矩阵) |O O| |I A| |O O | */
2.二分
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <iostream> #include <algorithm> #include <map> #include <set> #include <queue> using namespace std; int mod,n; struct matrix{ int f[33][33]; }h,t,tt; matrix mul(matrix a,matrix b)// { int i,j,k; matrix c; memset(c.f,0,sizeof(c.f)); for(i=0;i<n;i++) { for(j=0;j<n;j++) { for(k=0;k<n;k++) { c.f[i][j]+=a.f[i][k]*b.f[k][j]; c.f[i][j]%=mod; } } } return c; } matrix add(matrix a,matrix b) { int i,j; for(i=0;i<n;i++) { for(j=0;j<n;j++) a.f[i][j]=(a.f[i][j]+b.f[i][j])%mod; } return a; } matrix dfs(matrix e,int k) { if(k==1) { h=e; return e; } if(k%2) { t=dfs(e,k/2); tt=mul(h,e); t=add(t,add(mul(tt,t),tt)); h=mul(mul(h,h),e); } else { t=dfs(e,k/2); t=add(t,mul(h,t)); h=mul(h,h); } return t; } int main() { //printf("%d\n",32768*32768+32768); int k; while(scanf("%d%d%d",&n,&k,&mod)!=EOF) { int i,j; matrix e; for(i=0;i<n;i++) { for(j=0;j<n;j++) scanf("%d",&e.f[i][j]); } e=dfs(e,k); for(i=0;i<n;i++) { printf("%d",e.f[i][0]%mod); for(j=1;j<n;j++) printf(" %d",e.f[i][j]%mod); printf("\n"); } } return 0; } /* 2 100 10 1 2 3 4 ans: 4 6 4 8 2 100000000 10 1 2 3 4 ans: 0 0 0 0 3 99999 9999 1 2 3 4 5 6 7 8 9 ans: 6682 9965 3249 1582 2390 3198 6481 4814 3147 */