限制时间:3000ms,限制空间:131072K。
问题描述:给定一个n×n的矩阵A和一个正整数k,求S=A+A2+A3+…+Ak。 输入格式:输入只包含一个测试用例。第一行输入包含三个正整数n(n≤30),k(k≤10^9)和m(m<10^4)。然后跟随n行,每行包含n个小于32,768的非负整数,以行序优先给出A的元素。 输出格式:以A的方式输出S,每个元素模m。
输入用例
2 2 4
0 1
1 1
输出用例
1 2
2 3
import java.util.Scanner;
public class Main
{ static int MAXN=31;
static int n,k,m;
public static int [][] mult(int [][] a,int [][] b) //返回矩阵a和b相乘的矩阵
{ int n=a.length;
int [][] c=new int[n][n];
for (int i=0;i <n;i++)
for (int j=0;j <n;j++)
{ for (int k=0;k <n;k++)
c[i][j] += (a[i][k]*b[k][j]) % m;
c[i][j] %= m;
}
return c;
}
public static int [][] pow(int [][] a,int k) //返回a^k的矩阵
{ int n=a.length;
int [][] ans=new int[n][n]; //建立ans矩阵
for (int i=0;i <n;i++) //置ans为单位矩阵
ans[i][i]=1;
int [][] base=new int[n][n]; //建立base矩阵
for (int i=0;i <n;i++) //置base=a
for (int j=0;j <n;j++)
base[i][j]=a[i][j];
while(k!=0)
{ if ((k&1)==1) //遇到二进制位1
ans=mult(ans,base);
base=mult(base,base); //倍乘
k >>= 1; //右移一位
}
return ans;
}
public static void main(String[] args)
{ Scanner fin = new Scanner(System.in);
n = fin.nextInt();
k = fin.nextInt();
m = fin.nextInt();
int [][] a=new int[2*MAXN][2*MAXN];
for (int i=0;i <n;i++)
{ for (int j=0;j <n;j++)
a[i][j]=fin.nextInt();
a[n+i][i]=a[n+i][n+i]=1;
}
a=pow(a,k+1); //求出I+a+a^2+...+a^k
for (int i=0;i <n;i++)
{ for (int j=0;j <n;j++)
{ int e=a[n+i][j]%m;
if (i==j)
e=(e+m-1)% m; //减去I
if (j==n-1)
System.out.printf("%d\n",e);
else
System.out.printf("%d ",e);
}
}
}
}