[PKU 3233] Matrix Power Series [variation of matrix multiplication]

T i m e Time Time L i m i t : Limit: Limit: 3000 M S 3000MS 3000MS
M e m o r y Memory Memory L i m i t : Limit: Limit: 131072 K 131072K 131072K

Description

l i n k link link
Given a n × n n × n n×n matrix A A A and a positive integer k k k, find the sum S = A + A 2 + A 3 + … + A k S = A + A^2 + A^3 + … + A^k 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

analysis:

Direct calculation will overtime consider the matrix [A i − 1, S i − 2] [A^{i-1},S_{i-2}][Ai1,Si2]
[ A i , S i − 1 ] = [ A i − 1 , S i − 2 ] ∗ F [A^i,S_{i-1}]=[A^{i-1},S_{i-2}]*F [Ai,Si1]=[Ai1,Si2]F
F F F is thetransformation matrix,thenFFF :
A, EA, EA,E

O, E O, E O ,E
其中EEE represents theidentity matrix OOO is all0 00 matrix.
Note that theinitial matrixconstruction should beexpanded toconstruct
SSS is in theinitial matrix[1] [2] [1][2][1][2]

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll n,mod,k;
struct matrix{
    
    
	ll n,m;
	ll F[101][101];
}A,B,C;
matrix operator *(matrix a,matrix b)
{
    
    
	matrix c;
	c.n=a.n;c.m=a.m;
	for(int i=1;i<=c.n;i++)
		for(int j=1;j<=c.m;j++)
			c.F[i][j]=0;
	for(int k=1;k<=a.m;k++)
		for(int i=1;i<=c.n;i++)
			for(int j=1;j<=c.m;j++)
				c.F[i][j]=(c.F[i][j]+a.F[i][k]*b.F[k][j]%mod)%mod;  //矩阵乘法
	return c;
}
void ksm(ll x)
{
    
    
	if(x==1){
    
    
		B=A;
		return;
	}
	ksm(x/2);
	B=B*B;
	if(x&1) B=B*A;
}
int main(){
    
    
	scanf("%lld%lld%lld",&n,&k,&mod);
	C.n=n;C.m=2*n;A.n=n*2;A.m=n*2;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			scanf("%lld",&C.F[i][j]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			A.F[i][j]=C.F[i][j];
	for(int i=1;i<=n;i++)
		for(int j=n+1;j<=n+n;j++)
			if(i+n==j)  //赋单位矩阵
				A.F[i][j]=1;  //相当于初始矩阵[1][2]的初值
	for(int i=n+1;i<=n+n;i++)
		for(int j=n+1;j<=n+n;j++)
			if(i==j)  //同单位矩阵
				A.F[i][j]=1;  //初始矩阵[2][2]的初值
	ksm(k);
	C=C*B;
	for(int i=1;i<=n;i++)
	{
    
    
		for(int j=n+1;j<=n+n;j++)
			printf("%lld ",C.F[i][j]);  //输出[1][2]
		printf("\n");
	}
	
	return 0;
} 

Guess you like

Origin blog.csdn.net/dgssl_xhy/article/details/111330444