POJ 3233 Matrix Power Series——快速幂&&等比&&分治
题目
给定一个 $n \times n$ 的矩阵 $A$ 和正整数 $k$ 和 $m$。求矩阵 $A$ 的幂的和。
$$S = A + A^2 + ... + A^k$$
输出 $S$ 的各个元素对 $M$ 取余后的结果($1 \leq n \leq 30, 1 \leq k \leq 10^9, 1 \leq M \leq 10^4$)。
分析
数据范围 $n$ 很小,$k$ 很大,不肯能逐一求得。
由于具有等比性质,
设 $S_k = I + A + ... + A^{k-1}$
则有
$$\begin{pmatrix} A^k\\ S_k \end{pmatrix} = \begin{pmatrix} A & 0\\ I & I \end{pmatrix} \begin{pmatrix} A^{k-1}\\ S_{k-1} \end{pmatrix} = \begin{pmatrix} A & 0\\ I & I \end{pmatrix}^k\begin{pmatrix} I\\ 0 \end{pmatrix}$$
对这个新矩阵使用快速幂即可。
代码中的输出,使用了分块矩阵乘法的性质进行了简化。
#include<cstdio>
#include<cstring>
using namespace std; typedef long long ll;
struct matrix
{
int r, c;
int mat[][];
matrix(){
memset(mat, , sizeof(mat));
}
};
int n, k, p; matrix mul(matrix A, matrix B) //矩阵相乘
{
matrix ret;
ret.r = A.r; ret.c = B.c;
for(int i = ;i < A.r;i++)
for(int k = ;k < A.c;k++)
for(int j = ;j < B.c;j++)
{
ret.mat[i][j] = (ret.mat[i][j] + A.mat[i][k] * B.mat[k][j]) % p;
}
return ret;
} matrix mpow(matrix A, int n)
{
matrix ret;
ret.r = A.r; ret.c = A.c;
for(int i = ;i < ret.r;i++) ret.mat[i][i] = ;
while(n)
{
if(n & ) ret = mul(ret, A);
A = mul(A, A);
n >>= ;
}
return ret;
} int main()
{
scanf("%d%d%d", &n, &k, &p);
matrix a, b;
a.r = a.c = n;
for(int i = ;i < n;i++) for(int j = ;j < n;j++) scanf("%d", &a.mat[i][j]);
b.r = b.c = *n;
for(int i = ;i < n;i++)
{
for(int j = ;j < n;j++) b.mat[i][j] = a.mat[i][j];
b.mat[n+i][i] = b.mat[n+i][n+i] = ;
}
b = mpow(b, k+);
for(int i = ;i < n;i++)
for(int j = ;j < n;j++)
{
int tmp = b.mat[n+i][j] % p;
if(i == j) tmp = (tmp + p - ) % p;
printf("%d%c", tmp, j == n- ? '\n' : ' ');
}
}
还有一种经典的分治方法,
例如,
$A+A^2+A^3+A^4 = (A+A^2) + A^2(A + A^2)$,
$A+A^2+A^3+A^4+A^5 = (A+A^2) +A^3 + A^3(A + A^2)$.
因此,分k的奇偶递归一下就可以了。
#include<cstdio>
#include<cstring>
using namespace std; typedef long long ll;
struct matrix
{
int r, c;
int mat[][];
matrix(){
memset(mat, , sizeof(mat));
}
};
int n, k, p; matrix mul(matrix A, matrix B) //矩阵相乘
{
matrix ret;
ret.r = A.r; ret.c = B.c;
for(int i = ;i < A.r;i++)
for(int k = ;k < A.c;k++)
for(int j = ;j < B.c;j++)
{
ret.mat[i][j] = (ret.mat[i][j] + A.mat[i][k] * B.mat[k][j]) % p;
}
return ret;
} matrix mpow(matrix A, int n)
{
matrix ret;
ret.r = A.r; ret.c = A.c;
for(int i = ;i < ret.r;i++) ret.mat[i][i] = ;
while(n)
{
if(n & ) ret = mul(ret, A);
A = mul(A, A);
n >>= ;
}
return ret;
} matrix add(matrix A, matrix B)
{
matrix ret;
ret.r = A.r; ret.c = A.c;
for(int i = ;i < A.r;i++)
for(int j = ;j < A.c;j++)
ret.mat[i][j] = (A.mat[i][j] + B.mat[i][j]) % p;
return ret;
} matrix sum(matrix x, int k) //A+A^2+..+A^k
{
if(k == ) return x;
matrix s = sum(x, k/);
if(k & )
{
matrix tmp = mpow(x, k/+);
return add(s, add(tmp, mul(tmp, s)));
}
else
{
matrix tmp = mpow(x, k/);
return add(s, mul(tmp, s));
}
} int main()
{
scanf("%d%d%d", &n, &k, &p);
matrix a, ans;
a.r = a.c = n;
for(int i = ;i < n;i++) for(int j = ;j < n;j++) scanf("%d", &a.mat[i][j]);
ans = sum(a, k);
for(int i = ;i < n;i++) for(int j = ;j < n;j++) printf("%d%c", ans.mat[i][j], j == n- ? '\n' : ' ');
}
这个时间复杂度咋算啊?知道的大犇请留言。
参考链接:
1. https://blog.csdn.net/rowanhaoa/article/details/21023599
2. https://blog.csdn.net/scf0920/article/details/39345197
POJ 3233 Matrix Power Series——快速幂&&等比&&分治的更多相关文章
- 矩阵十点【两】 poj 1575 Tr A poj 3233 Matrix Power Series
poj 1575 Tr A 主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1575 题目大意:A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的 ...
- POJ 3233 Matrix Power Series 【经典矩阵快速幂+二分】
任意门:http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K To ...
- POJ 3233 Matrix Power Series(矩阵快速幂)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 19338 Accepted: 8161 ...
- poj 3233 Matrix Power Series(矩阵二分,高速幂)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 15739 Accepted: ...
- POJ 3233 Matrix Power Series (矩阵乘法)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 11954 Accepted: ...
- [ACM] POJ 3233 Matrix Power Series (求矩阵A+A^2+A^3...+A^k,二分求和或者矩阵转化)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 15417 Accepted: ...
- Poj 3233 Matrix Power Series(矩阵乘法)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Description Given a n × n matrix A and ...
- 线性代数(矩阵乘法):POJ 3233 Matrix Power Series
Matrix Power Series Description Given a n × n matrix A and a positive integer k, find the sum S = ...
- POJ 3233 Matrix Power Series(二分等比求和)
Matrix Power Series [题目链接]Matrix Power Series [题目类型]二分等比求和 &题解: 这题我原来用vector写的,总是超时,不知道为什么,之后就改用 ...
随机推荐
- dubbo学习之路-SPI机制
dubbo学习之路-SPI机制 1.SPI 1.1Java SPI 原理 SPI是service provider interface简称.在java JDK中 内置的一种服务提供发现机制.它解决在一 ...
- (三)linux 学习 --操作文件和目录
The Linux Command Line 读书笔记 - 部分内容来自 http://billie66.github.io/TLCL/book/chap05.html 文章目录 通配符 字符范围 ` ...
- Django RuntimeError: Model class app_anme.models.Ad doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.报错
报错内容 RuntimeError: Model class app_anme.models.Ad doesn't declare an explicit app_label and isn't in ...
- scope:provided影响子依赖
一.问题 在上一篇<SpringBoot项目启动不走内嵌容器>中发现,provided会影响子依赖. 标记为scope:provided的jar在编译和运行时有作用,表明了运行时depen ...
- c# webapi 过滤器token、sign认证、访问日志
1.token认证 服务端登录成功后分配token字符串.记录缓存服务器,可设置有效期 var token = Guid.NewGuid().ToString().Replace("-&qu ...
- openssl jia adress
???????????????????????????????????????????openssl证IP 首先创建openssl.cnf, 内容如下. 其中organizationalUnitNam ...
- js 简单的滑动1
js 简单的滑动教程(一) 作者:Lellansin 转载请标明出处,谢谢 首先我们要实现一个简单的滑动,三张图.点击左边向左滑动,点右向右滑,碰到临界值的时候就不能滑动. 这个简单滑动的原理是, ...
- Web Api 转
GET:生到数据列表(默认),或者得到一条实体数据 POST:添加服务端添加一条记录,记录实体为Form对象 PUT:添加或修改服务端的一条记录,记录实体的Form对象,记录主键以GET方式进行传输 ...
- C++线程同步之临界区
#include <iostream> #include <windows.h> using namespace std; CRITICAL_SECTION cs; // Lo ...
- ActiveMQ Topic持久化订阅的几点收获
非持久化模式下,Topic不会落地任何消息,消息入队即出队, 消费者如果想要保留离线后的消息需要告诉MQ实例,即注册过程, 代码上大概是这样的: connectionFactory = new Act ...