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写的,总是超时,不知道为什么,之后就改用 ...
随机推荐
- linux 下用C实现 ATM 自动取款机功能 (进程间通信)
直接先上图: 项目需求: 主要分为两人大模块: 客户端 .进入时的功能开户.销户.登录.解锁 开户:输入姓名.身份证号.设置密码,如果开户成功,则服务器上保存一个账号信号(一个账号存一个文件,文件名建 ...
- 转:深入浅出Java垃圾回收机制
原文链接:http://www.importnew.com/1993.html 对于Java开发人员来说,了解垃圾回收机制(GC)有哪些好处呢?首先可以满足作为一名软件工程师的求知欲,其次,深入了解G ...
- String 字符串的==和eqauls区别
1.对于基本类型来说,==比较的是数据的值,equals方法也是数据的值: 对于引用类型来说,==比较的是引用的地址,equals方法比较的是对象的内容. 2.String是引用类型,用“=”创建字符 ...
- vue 关于子组件向父组件传值$emit触发无效问题
先贴上代码 子组件代码 //子组件请求接口,用自己封装的axios getupdate(){ this.$post({ url:this.$apis.unitupdate, postType:'jso ...
- HBuilderX打包成安卓或苹果app之后的调试问题,避免每次都要打包
一.使用VScode安装 Live Server插件 二.使用:安装成功后---->>新建一个index.html 写入内容如下图所示 注:href地址是你在电脑上启动该项目的访问地址(此 ...
- JS 中Json常用操作
转自: https://www.jianshu.com/p/6501b0f3124f 直接定义json var json = {"name": "小明", &q ...
- Jmeter学习笔记(十四)——逻辑控制器
一.逻辑控制器简单介绍 Jmeter中逻辑控制器(Logic Controllers)的作用域只对其子节点的sampler有效,作用是控制采样器的执行顺序.放在逻辑控制器下面的所有的采样器都会当做一个 ...
- django admin日期变为可以修改
Django - 日期.时间字段 阅读目录 DateTimeField.auto_now DateTimeField.auto_now_add admin中的日期时间字段 如何将创建时间设置为“默 ...
- laravel使用withCount获取列表下关联模型的数量
模型里面 <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model ...
- python(字符串函数)
一.字符串函数 1.首字母大小写 capitalize() title() name = "xinfangshuo" print (name.capitalize()) print ...