2020 BIT冬训-二分三分快速幂矩阵 I - Matrix Power Series POJ - 3233(矩阵快速幂,分治思想(吧))
Problem Description
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
Output
Output the elements of S modulo m in the same way as A is given.
Sample Input
2 2 4 0 1 1 1
Sample Output
1 2 2 3
这题需要计算A+A2+A3+…+Ak.
令Sk=A+A2+A3+…+AK,则Sk=(1+Ak/2)*(A1+A2+A3+…+AK/2)(+AK)(若k为偶数则不用加,若k为奇数则加上)。
即SK=(1+AK/2)*SK/2(+AK)(若k为偶数则不用加,若k为奇数则加上)(1为单位矩阵)。
其中左边的因子用快速幂求出来,右边的Sk/2使用递归计算得出即可。
最后还需要判断下k的奇偶性来决定是否加上AK
AC代码如下(大部分是借鉴这个的。因为一开始确实有点超过我的能力范围,我会再单独多敲几遍的qwq)
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,k,mod; typedef struct Mar{ int m[35][35]; void Init(){//单位矩阵 memset(m,0,sizeof(m)); for(int i=0;i<35;i++) m[i][i]=1; } }Martrix; Martrix Add(Martrix a,Martrix b){//矩阵加法 Martrix c; for(int i=0;i<n;i++) for(int j=0;j<n;j++) c.m[i][j]=(a.m[i][j]+b.m[i][j])%mod; return c; } Martrix Multi(Martrix a,Martrix b){//矩阵乘法 Martrix c; for(int i=0;i<n;i++) for(int j=0;j<n;j++){ c.m[i][j]=0; for(int k=0;k<n;k++) c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod; c.m[i][j]%=mod; } return c; } Martrix Quick_mod(Martrix a,int k){//快速幂 Martrix ans; ans.Init(); while(k){ if(k&1) ans=Multi(ans,a); k>>=1; a=Multi(a,a); } return ans; } Martrix Outans(Martrix a,int k){ if(k==1) return a; Martrix ans; ans.Init(); ans=Add(ans,Quick_mod(a,k>>1)); ans=Multi(ans,Outans(a,k>>1)); if(k&1) ans=Add(ans,Quick_mod(a,k)); return ans; } int main(){ scanf("%d%d%d",&n,&k,&mod); Martrix a; for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&a.m[i][j]); Martrix ans=Outans(a,k); for(int i=0;i<n;i++) for(int j=0;j<n;j++){ printf("%d ",ans.m[i][j]); if(j==n-1) printf("\n"); } }

浙公网安备 33010602011771号