【poj3233Matrix Power Series】二分+矩阵乘法或矩阵套矩阵乘法

矩阵乘法啊啊啊233 POJ3233
Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072K
Total Submissions: 27042 Accepted: 11027

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

Source

POJ Monthly--2007.06.03, Huang, Jinsong
这道题思维难度并不大,有两种方法实现
1.二分+矩阵乘法。
因为我们知道对于 x^(2*n) == x^n * ( 1 + x^n)
那么我们可以一直递归下去。
伪代码:
matrix getsum(int x)
{
	if(x==1) return A;
	if(x&1) return getsum(x-1)*A;
	else return getsum(x/2) * ( A^(x/2) + 1 );
}
2.矩阵套矩阵。 如果我们不看这个A是一个矩阵的话,那么我们看这不就是一个矩阵乘法等比数列求和板题吗?是的,类同那种写法,只是在矩阵里面套的数字也是一个矩阵。 下面只给出二分法的代码:
#include<cstdio>
#include<iostream>
using namespace std;
int n,k,mod;

struct arr
{
	int a[35][35];
};
arr A;
arr jzjf(arr A,arr B)
{
	arr C;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) C.a[i][j] = 0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			C.a[i][j] = ( A.a[i][j] + B.a[i][j] )%mod; 
		}
	}
	return C;
}
arr dw;
arr jzcf(arr A,arr B)
{
	arr C;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) C.a[i][j] = 0;
	for(int i=1;i<=n;i++) 
	{
		for(int j=1;j<=n;j++)
		{
			for(int k=1;k<=n;k++)
			{
				C.a[i][j] = (C.a[i][j] + A.a[i][k]*B.a[k][j]%mod)%mod;
			}
		}
	}
	return C;
}
arr jzksm(int kkk)
{
	arr C; arr D;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(i==j) C.a[i][j] = 1;
			else C.a[i][j] = 0;
		}
	}
	D=A;
	for(;kkk;kkk>>=1,D=jzcf(D,D))
		if(kkk&1) C=jzcf(C,D);
	return C; 
}

arr getsum(int x)
{
	if(x==1) return A;
	if(x&1) return jzjf( jzksm(x) , getsum(x-1) );
	else
	{
		arr aha = getsum(x/2);
		return jzjf(jzcf(aha,jzksm(x/2)),aha);
	}
}
int main()
{
	
	scanf("%d%d%d",&n,&k,&mod);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&A.a[i][j]);
			A.a[i][j] %= mod;
		}
	}
	for(int i=1;i<=n;i++) dw.a[i][i] = 1;
	arr ans = getsum(k);
	for(int i=1;i<=n;i++) 
	{
		for(int j=1;j<=n;j++)
		{
			ans.a[i][j]=(ans.a[i][j]%mod+mod)%mod;
			printf("%d ",ans.a[i][j]%mod);
		}
		puts("");
	}
	return 0;
	
	
}
 
posted @ 2018-06-11 18:17  Newuser233  阅读(12)  评论(0)    收藏  举报