关闭

POJ - 3233 Matrix Power Series

标签: 快速幂矩阵快速幂
1635人阅读 评论(0) 收藏 举报
分类:

题目:

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,难怪过不了。

0
0
查看评论

POJ3233 Matrix Power Series 矩阵快速幂+二分求和

在看矩阵快速幂求和之前,我们先来看一下等比数列Sn=(a+a^2+a^3+...+a^n)mod M的求和取模: 实现代码如下: #include #include #include using namespace std; typedef long long LL; const ...
  • AC_Gibson
  • AC_Gibson
  • 2015-06-09 16:10
  • 465

矩阵十大经典题目之三-POJ-3233-Matrix Power Series-两次二分

如果k为偶数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)    如果k为奇数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)+A^k 然后二分求解即可。...
  • rowanhaoa
  • rowanhaoa
  • 2014-03-11 16:48
  • 1869

POJ 3233 Matrix Power Series(矩阵快速幂+二分)

题目地址:POJ 3233 题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加)。输出的数据mod m。k     这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二...
  • u013013910
  • u013013910
  • 2014-09-17 17:06
  • 1075

poj 3233 Matrix Power Series

点击打开poj 3233 思路: 二分求和+矩阵快速幂 分析: 1 题目给定一个n*n的矩阵A,要求(A+A^2+....A^K)%m后的矩阵 2 对于任意的A^x,我们都能够利用矩阵快速幂求出,但是我们现在要求的是和。    仔细观察整个式子,那么我们可以对原式进行变...
  • cgl1079743846
  • cgl1079743846
  • 2013-08-28 16:25
  • 1732

Poj 3233 Matrix Power Series

题目连接:http://poj.org/problem?id=3233 本题练习矩阵运算。 需要两次用到二分法,求和一次,求幂一次。 二分法的知识参考我以前写过的一篇关于二分法的思考:http://blog.csdn.net/niuox/article/details/7226471&...
  • niuox
  • niuox
  • 2012-12-02 16:02
  • 869

POJ 3233 Matrix Power Series

矩阵快速幂+二分求前n项和     矩阵快速幂是有模板的,多做几道题就会理解,前提是要会快速幂取模;    之所以用二分是因为求和的过程:A^1+A^2...+A^(k-1)+A^k,   k是1e9的,所以暴力求和肯定会TLE,在网上找到 了...
  • u011041349
  • u011041349
  • 2014-09-10 22:37
  • 552

poj 3233 Matrix Power Series

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

poj 3233 Matrix Power Series

考查矩阵乘法
  • u014686462
  • u014686462
  • 2014-07-02 13:49
  • 441

Matrix Power Series POJ - 3233

Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + ...
  • fire_lch316
  • fire_lch316
  • 2017-08-22 10:12
  • 54

POJ 3233 Matrix Power Series

这道题的题意很简单,就是求S = A + A2 + A3 + … + Ak的值。我们可以先把上式提取公因式,若k为偶数S = A + A2 + A3 ...
  • zhaofukai
  • zhaofukai
  • 2011-04-18 19:25
  • 541
    个人资料
    • 访问:1072826次
    • 积分:19315
    • 等级:
    • 排名:第537名
    • 原创:786篇
    • 转载:0篇
    • 译文:0篇
    • 评论:114条
    博客专栏