POJ - 3233 Matrix Power Series

原创 2016年08月29日 15:04:05

题目:

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 nnonnegative 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

有个题目和这个很像,点击打开我的博客

和那个题目一样,这个题目我也有2种思路。

第一种思路:用S(k/2)求S(k),快速幂

超时的代码:

#include<iostream>
using namespace std;

int n, k, m;
long long in[30][30];
long long list[30][30];
long long temp[30][30];
long long sum[30][30];

void pro(long long l1[][30], long long l2[][30], long long t[][30])	//t=l1*l2
{
	for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)
	{
		t[i][j] = 0;
		for (int k = 0; k < n; k++)t[i][j] = (t[i][j] + l1[i][k]%m * l2[k][j]%m) % m;
	}
}

void f(int num)		//list=in^num
{
	if (num == 1)
	{
		for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)
			list[i][j] = in[i][j] % m;
		return;
	}
	f(num / 2);
	pro(list, list, temp);
	if (num % 2)pro(temp, in, list);
	else for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)list[i][j] = temp[i][j];
}

void getsum(int num)	
{
	if (num == 1)
	{
		for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)sum[i][j] = in[i][j]%m;
		return;
	}
	getsum(num / 2);
	f(num / 2);
	pro(sum, list, temp);
	for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)
		sum[i][j] = (sum[i][j] + temp[i][j]) % m;
	if (num % 2)
	{
		pro(sum, in, temp);
		for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)
			sum[i][j] = (temp[i][j] + in[i][j]) % m;
	}
}

int main()
{
	cin >> n >> k >> m;
	for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)cin >> in[i][j];
	getsum(k);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (j)cout << " ";
			cout << sum[i][j];
		}
		cout << endl;
	}
	return 0;
}

这个代码的时间是(log k)^2 / 2 * n*n

这个我感觉不太大才对,毕竟只有1组数据,但是超时了。

我知道矩阵快速幂的效率更高,于是看这个能不能过。


第二种思路:用S(k-1)求S(k),矩阵快速幂

S(k)=S(k-1)*A +A



下面的代码中in就是中间这个大矩阵。

只需要求出list=in^k 即可求出S(k)

假设


那么

S(k)=CA

其中C可以从list的右上角抠出来,A可以从in的左上角抠出来。

代码:

#include<iostream>
using namespace std;

int n, k, m;
long long in[60][60];
long long list[60][60];
long long temp[60][60];

void pro(long long l1[][60], long long l2[][60], long long t[][60])	//t=l1*l2
{
	for (int i = 0; i < n*2; i++)for (int j = 0; j < n*2; j++)
	{
		t[i][j] = 0;
		for (int k = 0; k < n * 2; k++)t[i][j] = (t[i][j] + l1[i][k] * l2[k][j]) % m;
	}
}
void f(int num)		//list=in^num
{
	if (num == 0)
	{
		for (int i = 0; i < n*2; i++)for (int j = 0; j < n*2; j++)
			list[i][j] = (i == j);
		return;
	}
	f(num / 2);
	pro(list, list, temp);
	if (num % 2)pro(temp, in, list);
	else for (int i = 0; i < n*2; i++)for (int j = 0; j < n*2; j++)list[i][j] = temp[i][j];
}

int main()
{
	cin >> n >> k >> m;
	for (int i = 0; i < n * 2; i++)for (int j = 0; j < n * 2; j++)
		in[i][j] = (i == j || i+n == j );
	for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)cin >> in[i][j];
	f(k);
	long long r;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (j)cout << " ";
			r = 0;
			for (int k = 0; k < n; k++)r += list[i][k + n] * in[k][j];
			cout << r%m;
		}
		cout << endl;
	}
	return 0;
}

这个代码的时间是,log k *(n*2)*(n*2)

这个代码是922ms AC的,前面的代码大约是4倍的时间,也就是大约4s,限时是3s,难怪过不了。

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

poj 3233 Matrix Power Series

还是矩阵的快速幂。。。 只要令Sk=I+A+A^2+.....A^(k-1)   则有   Ak  =  |  A  0  |    Ak-1  =  | A 0 ...

POJ 3233 Matrix Power Series

运用两次二分,对Ak运用快速幂,对S用二分处理(求一个递归式) 题意:求 S=A+A2+A3+ … +Ak. 思路:AK首先想到矩阵快速幂。 1.当K为奇数时,如K=5时 sum(5)=A+A^2+A...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

poj 3233 Matrix Power Series

分类:分治 难度:1.5   题意:给定矩阵a,求s=a^1+…+a^k,结果mod m。矩阵乘法,两次分治,计算a^k和a^1+…+a^k。即a^k=(a*a)^(k/2), a^1+...+a...

POJ 3233 Matrix Power Series

//思路:可以把Sn放进矩阵里参与运算 #include #include using namespace std; typedef vector vec; typedef vector mat; i...

poj 3233 Matrix Power Series

最近一直在做矩阵的题目,这算是一道简单题目吧。 建立一个矩阵的结构体,便于赋值和返回值。 S = A + A2 + A3 + … + Ak     如果 S=A+A2 +...

POJ 3233 Matrix Power Series

矩阵快速幂+二分求前n项和     矩阵快速幂是有模板的,多做几道题就会理解,前提是要会快速幂取模;    之所以用二分是因为求和的过程:A^1+A^2...+A^(k-1)+A^k,   k是1...

POJ 3233 Matrix Power Series

矩阵乘法+倍增

poj 3233 Matrix Power Series

第一次接触矩阵这东西,不怎么会; 矩阵乘法:自学百度;快速幂:自学百度; k为偶数时:A^1+A^2+..+A^k==(A^1+..+A^(k/2))*A^(k/2)+(A^1+...+A^(k/...

poj 3233 Matrix Power Series

矩阵快速幂,最后求和的时候还要采用二分的思想,递归求和,

[POJ]3233. Matrix Power Series

Analysis     找了几道矩阵乘法的题目练一练,这道是最水的。大意是给定N*N矩阵A,求A+A^1+A^2+....+A^k。那么使用二分的方法,将要求的矩阵变形为 A+A^1+A^2+....
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)