题意:对于任意给定的r阶方阵A,求S[n]=A+A2+A3+…+An
分析:
考虑1×2的矩阵【An-1,S[n-2]】,注意此1×2矩阵的2个元素都是r阶方阵!我们希望通过乘以某2×2的矩阵M,得到1×2的矩阵【An,S[n-1]】=【An-1*A, An-1+S[n-2]】
容易构造出此矩阵M为:
A |
E |
O |
E |
其中4个元素均为r阶方阵,O表示r阶全0矩阵,E表示单位矩阵(主对角线上为1,其它全为0)。然后用矩阵乘法快速幂算一下就好啦。
代码:
type arrr=array[1..30,1..30] of longint; arr=array[1..2,1..2,1..30,1..30] of longint; var n,m,p,i,j,k:longint; ans,a,u:arrr; c,d:arr; procedure cheng1(x,y:longint;a,b:arrr); var i,j,k:longint; begin for i:=1 to n do for j:=1 to n do for k:=1 to n do c[x,y,i,j]:=(c[x,y,i,j]+a[i,k]*b[k,j]) mod p; end; procedure cheng(a,b:arr); var i,j,k:longint; begin for i:=1 to 2 do for j:=1 to 2 do begin fillchar(c[i,j],sizeof(c[i,j]),0); for k:=1 to 2 do cheng1(i,j,a[i,k],b[k,j]) end; end; procedure ksm(x:longint); begin if x<=1 then exit; ksm(x div 2); cheng(c,c); if x mod 2=1 then cheng(c,d); end; begin readln(n,m,p); for i:=1 to n do for j:=1 to n do read(a[i,j]); for i:=1 to n do u[i,i]:=1; d[1,1]:=a; d[1,2]:=u; d[2,2]:=u; c:=d; ksm(m); for i:=1 to n do for j:=1 to n do for k:=1 to n do ans[i,j]:=(ans[i,j]+a[i,k]*c[1,2,k,j]) mod p; for i:=1 to n do for j:=1 to n do if j<n then write(ans[i,j],' ') else writeln(ans[i,j]); end.