poj3233 题解 矩阵乘法 矩阵快速幂
题意:求S = A + A2 + A3 + … + Ak.(mod m)
这道题很明显可以用矩阵乘法,但是这道题的矩阵是分块矩阵,
分块矩阵概念如下:当一个矩阵A中的单位元素aij不是一个数值而是一个矩阵是A矩阵称为分块矩阵,在性质满足的前提下依然满足矩阵加法乘法。 例如矩阵乘法A×B,将B按行分块,可以看成矩阵A乘列向量,其中B中每个元素是一个行向量;将A按列分块同理。
简单地说,就是矩阵里的元素还是个矩阵。这道题我们可以像这样构建矩阵:
∵Sn=Sn-1+Ak ∴有如下转移图

写出邻接矩阵 (下图用E表示单位矩阵 也就是"1”,0表示全是0的矩阵 也就是“0”,A即为输入的矩阵)

也就有:




最终答案是:


所以,最终C++程序只需要重载运算符就可以轻松AC了

而另一种做法,也就是二分加矩阵快速幂则需要较长时间(800+MS)

#include <iostream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cstdio>
#include <cstdlib> using namespace std; int n,k,m; class Matrix
{
public:
int val[][];
int x,y; Matrix()
{
memset(val,,sizeof(val));
x=y=;
return ;
} void set_E()
{
int i;
for(i=;i<=x;++i)
val[i][i]=;
return ;
} Matrix operator*(Matrix b)
{
int i,j,k;
Matrix c;
c.resize(x,b.y); for(k=;k<=b.x;++k)
for(i=;i<=x;++i)
if(val[i][k])//不加这行就要340+MS
for(j=;j<=b.y;++j)
c.val[i][j]=(c.val[i][j]+val[i][k]*b.val[k][j])%m;
return c;
} Matrix operator+(Matrix b)
{
Matrix c;
c.resize(max(x,b.x),max(y,b.y));
int i,j; for(i=;i<=c.x;++i)
for(j=;j<=c.y;++j)
c.val[i][j]=(val[i][j]+b.val[i][j])%m; return c;
} void resize(const int & _x,const int & _y)
{
x=_x,y=_y;
return ;
}
}A; class Matrix_Plus
{
public:
Matrix val[][];
int x,y; Matrix_Plus()
{
memset(val,,sizeof(val));
x=y=;
return ;
} void set_E()
{
int i;
for(i=;i<=x;++i)
val[i][i].set_E();
return ;
} Matrix_Plus operator*(Matrix_Plus b)
{
Matrix_Plus c;
int i,j,k;
c.resize(x,b.y); for(k=;k<=b.x;++k)
for(i=;i<=x;++i)
for(j=;j<=b.y;++j)
c.val[i][j]=c.val[i][j]+val[i][k]*b.val[k][j];
return c;
} Matrix_Plus operator^(int p)
{
Matrix_Plus r,base;
r.resize(,);
r.val[][].resize(n,n);
r.val[][].resize(n,n);
r.val[][].resize(n,n);
r.val[][].resize(n,n);
r.set_E();
base=*this; while(p)
{
if(p&)
r=r*base;
base=base*base;
p>>=;
} return r;
} void resize(const int & _x,const int & _y)
{
x=_x,y=_y;
return ;
} }S,A_; int main()
{
int i,j; scanf("%d%d%d",&n,&k,&m);
A.resize(n,n); for(i=;i<=n;++i)
{
for(j=;j<=n;++j)
{
scanf("%d",&A.val[i][j]);
}
} S.resize(,);
S.val[][]=A;
S.val[][].resize(n,n);
S.val[][].resize(n,n); A_.resize(,);
A_.val[][].resize(n,n);
A_.val[][].resize(n,n);
A_.val[][].resize(n,n);
A_.val[][].resize(n,n);
A_.val[][].set_E();
A_.val[][].set_E();
A_.val[][]=A;
S=S*(A_^k); for(i=;i<=n;++i)
{
for(j=;j<=n;++j)
printf("%d ",S.val[][].val[i][j]);
printf("\n");
}
return ;
}
poj3233 题解 矩阵乘法 矩阵快速幂的更多相关文章
- Luogu 3390 【模板】矩阵快速幂 (矩阵乘法,快速幂)
Luogu 3390 [模板]矩阵快速幂 (矩阵乘法,快速幂) Description 给定n*n的矩阵A,求A^k Input 第一行,n,k 第2至n+1行,每行n个数,第i+1行第j个数表示矩阵 ...
- Luogu T7152 细胞(递推,矩阵乘法,快速幂)
Luogu T7152 细胞(递推,矩阵乘法,快速幂) Description 小 X 在上完生物课后对细胞的分裂产生了浓厚的兴趣.于是他决定做实验并 观察细胞分裂的规律. 他选取了一种特别的细胞,每 ...
- HDU4965 Fast Matrix Calculation —— 矩阵乘法、快速幂
题目链接:https://vjudge.net/problem/HDU-4965 Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Othe ...
- bzoj 3240: [Noi2013]矩阵游戏 矩阵乘法+十进制快速幂+常数优化
3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 613 Solved: 256[Submit][Status] ...
- poj3613:Cow Relays(倍增优化+矩阵乘法floyd+快速幂)
Cow Relays Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7825 Accepted: 3068 Descri ...
- BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 ...
- bzoj 3240 矩阵乘法+十进制快速幂
首先,构造出从f[][i]->f[][i+1]的转移矩阵a,和从f[i][m]->f[i+1][1]的转移矩阵b, 那么从f[1][1]转移到f[n][m]就是init*(a^(m-1)* ...
- 【HDOJ5950】Recursive sequence(矩阵乘法,快速幂)
题意:f[1]=a,f[2]=b,f[i]=2f[i-2]+f[i-1]+i^4(i>=3),多组询问求f[n]对2147493647取模 N,a,b < 2^31 思路:重点在于i^4的 ...
- 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)
先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...
随机推荐
- JSP-Runood:JSP 客户端请求
ylbtech-JSP-Runood:JSP 客户端请求 1.返回顶部 1. JSP 客户端请求 当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信息 ...
- Word中公式和文字混排对齐的问题
全选-字体-字符间距-位置-标准-确定 段落-中文版式-文本对齐方式-居中-确定
- PCB 脱离IIS的Web应用
在用.net Web编程中,我们写好的Web应用首选会挂在IIS上面,因为它足稳定并且功能齐全,但这不是我们唯一的选择,微软给我们提供了Owin组件,Web应该的宿主可以不再是IIS了,有了Owin后 ...
- 8.22 NOIP 模拟题
8.22 NOIP 模拟题 编译命令 g++ -o * *.cpp gcc -o * *.c fpc *.pas 编译器版本 g++/gcc fpc 评测环境 位 Linux, .3GHZ CPU ...
- linux如何更改yum源
更改linux yum源方法:第一步:进入yum配置文件目录:cd /etc/yum.repos.d/第二步:备份配置文件(如果后续出现了问题就可以恢复):mv CentOS-Base.repo Ce ...
- Coursera公开课-Machine_learing:编程作业7
这周的编程作业主要是两方面内容. 1.K-means聚类. 2.PCA(Principle Component Analys)主成分分析. 方式主要是通过对图像的聚类实现压缩图像,后来发现PCA也可以 ...
- 338 Counting Bits Bit位计数
给定一个非负整数 num. 对于范围 0 ≤ i ≤ num 中的每个数字 i ,计算其二进制数中的1的数目并将它们作为数组返回.示例:比如给定 num = 5 ,应该返回 [0,1,1,2,1,2] ...
- 10 在C#中读取文件
我们在前一个练习中已经了解了如何在C#控制台程序(console)中读取用户的输入.现在我们要学习如何从一个文件中读取内容.在下面的练习中,你要格外小心.关于文件的操作,一不小心会损失你的重要文件. ...
- nginx设置绑定解析实现二级域名多域名
apache(httpd)配置多个二级域名看这个链接:https://www.cnblogs.com/Crazy-Liu/p/10879928.html 网站的目录结构为/home/www├── bb ...
- 《LeetCode-0004》 寻找两个有序数组的中位数-Median of Two Sorted Arrays
题目给定两个大小为 m 和 n 的有序数组nums1和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2 ...