矩阵快速幂/矩阵加速线性数列 By cellur925
讲快速幂的时候就提到矩阵快速幂了啊,知道是个好东西,但是因为当时太蒟(现在依然)没听懂。现在把它补上。
一、矩阵快速幂
首先我们来说说矩阵。在计算机中,矩阵通常都是用二维数组来存的。矩阵加减法比较简单易懂,两个矩阵相加减就是两个行列数均相等的矩阵的对应位置的数相加减。
矩阵乘法就有些复杂了。它有一些特殊的要求,要求参与矩阵乘法运算的第一个矩阵的列数等于第二个矩阵的行数。所得的矩阵列数为第一个矩阵的列数,行数为第二个矩阵的行数。
举个栗子。
另外矩阵乘法有一些性质。满足结合律与分配律,不满足交换律(这很好理解)。
这是矩阵。
快速幂就比较显然了,我们先来复习一下快速幂的代码。
long long poww(long long a,long long b)
{
long long ans=;
while(b>)
{
if(b&) ans=ans*a%k;
b>>=;
a=a*a%k; }
return ans; }
那么矩阵快速幂就不难理解了。设指数为k,我们可以用一个ans矩阵来代表最后结果,运行ksm函数。
ans的初值在ij相等时应为1.
个人习惯用结构体+二维数组存储矩阵。
(这里应该有代码)
至于模数,我们可以理性愉悦地运用膜的性质。
二、优化线性数列
这里省掉奇幻的引入用斐波那契栗子 喵~
我们直接看方法。
我们第一步需要构造基准矩阵,这也是最难的地方,想了好久才大概总结出一个方法。(还可能不对呢)
我们拿斐波那契数列来开刀:
f[i]=f[i-]+f[i-]
对于f[i],找到最深需要追溯到的之前的值。在这里是f[i-2]。于是我们可以得到初始矩阵
-----------
| f[i-] |
| |
| f[i-] |
| |
|---------|
目标矩阵
------------
| f[i] |
| |
| |
| f[i-] |
| |
-------------
(这里比较玄学 感性理解qwq)
-----------
| f[i-1] |
| |
| f[i-2] |
-----------
|
|
|
------------
| f[i] |
| |
| |
| f[i-1] |
| |
-------------
我们知道
f[i]=*f[i-]+*f[i-]
f[i-]=*f[i-]+*f[i-]
于是取出他们的系数,得到
这里贴出LuoguP1939的代码
#include<cstdio>
#include<algorithm>
#include<cstring> using namespace std;
typedef long long ll;
const ll moder=1e9+; int T;
ll n;
struct matrix{
ll m[][];
}ans,sta; void init()
{
memset(ans.m,,sizeof(ans.m));
for(int i=;i<=;i++) ans.m[i][i]=;
memset(sta.m,,sizeof(sta.m));
sta.m[][]=sta.m[][]=sta.m[][]=sta.m[][]=;
} matrix mul(matrix a,matrix b)
{
matrix tmp;
memset(tmp.m,,sizeof(tmp.m));
for(int i=;i<=;i++)
for(int j=;j<=;j++)
for(int k=;k<=;k++)
(tmp.m[i][j]+=(a.m[i][k]%moder)*(b.m[k][j]%moder))%=moder;
return tmp;
} void ksm(ll p)
{
while(p)
{
if(p&) ans=mul(ans,sta);
p>>=;
sta=mul(sta,sta);
}
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
if(n<=){printf("1\n");continue;}
init();
ksm(n);
printf("%lld\n",ans.m[][]);
}
return ;
}
未完待续
矩阵快速幂/矩阵加速线性数列 By cellur925的更多相关文章
- 矩阵乘法&矩阵快速幂&矩阵快速幂解决线性递推式
矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b * A B = a*A+b*C a*c+b*D c d ...
- POJ 3734 Blocks(矩阵快速幂+矩阵递推式)
题意:个n个方块涂色, 只能涂红黄蓝绿四种颜色,求最终红色和绿色都为偶数的方案数. 该题我们可以想到一个递推式 . 设a[i]表示到第i个方块为止红绿是偶数的方案数, b[i]为红绿恰有一个是偶数 ...
- POJ3233 Matrix Power Series 矩阵快速幂 矩阵中的矩阵
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 27277 Accepted: ...
- hdu 4965 矩阵快速幂 矩阵相乘性质
Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Jav ...
- hihocoder第42周 3*N骨牌覆盖(状态dp+矩阵快速幂)
http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] ...
- 矩阵快速幂---BestCoder Round#8 1002
当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?可以用矩阵快速幂来加速计算.我们可以用矩阵来表示数列递推公式比如fibonacci数列 可以表示为 [f(n) f(n-1)] = [f(n ...
- uva11551矩阵快速幂
题目看了半天没看懂,,就是把一个数列更新r次,每次更新就是计算和,就是每一个数,只要出现了的表号都要加上去,具体看代码 矩阵快速幂实现加速 #include<map> #include&l ...
- 解题报告:poj 3070 - 矩阵快速幂简单应用
2017-09-13 19:22:01 writer:pprp 题意很简单,就是通过矩阵快速幂进行运算,得到斐波那契数列靠后的位数 . 这是原理,实现部分就是矩阵的快速幂,也就是二分来做 矩阵快速幂可 ...
- HDU5950 Recursive sequence 非线性递推式 矩阵快速幂
题目传送门 题目描述:给出一个数列的第一项和第二项,计算第n项. 递推式是 f(n)=f(n-1)+2*f(n-2)+n^4. 由于n很大,所以肯定是矩阵快速幂的题目,但是矩阵快速幂只能解决线性的问题 ...
随机推荐
- httpclient失败重连机制
HttpClient 底层会默认超时自动重发3次,DefaultHttpRequestRetryHandler源码 /** * Create the request retry handler ...
- vi和vim上查找字符串
方法/步骤 1 我们以samba的配置文件为例,搜索一个user的字符串. vim /etc/samba/smb.conf 打开smb.conf 2 命令模式下,输入/user "/&quo ...
- win8系统 重装系统如何删除EFI分区
在PE下(一般重装系统就是在PE下),依次输入如下命令(注意虽然显示的是中文名"磁盘0",但是还是用英文disk 0) list disk select disk 0 clean
- 在调试C++程序是出现这个问题的解决方案illegal pure syntax, must be '= 0'
笔者在调试c++的时候遇见了这个问题 E:\Data Struct\SqString\新建 文本文档.cpp(5) : error C2258: illegal pure syntax, must b ...
- SpringMVC+MyBatis+JMS+JTA(分布式事务)
SpringMVC+MyBatis 相信已经是如今企业开发中经常使用技术了. 由于一些需求,我们须要集成JMS(我使用的是ActiveMQ).大家应该都知道.MQ也能够觉得是一个数据源.数据也是数据源 ...
- ./configure && make && make install详解 (转)
在Linux中利用源码包安装软件最重要的就是要仔细阅读安装包当中的README INSTALL两个说明文件,这两个文件会清楚的告诉你如何可以正确的完成这个软件的安装! 我们都知道源码包安装分为这么几个 ...
- adb端口被占用情况下如何杀掉进程
1.CMD命令窗口输入:adb nodaemon server .然后就会提示你哪个端口被占用了. 2.输入netstat -ano | findstr "5037" .然后会弹出 ...
- 不等式数列 DP
度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于和小于符号(即 '>' 和 '<' )使其成为一个合法的不等式数列.但是现在度度熊手中只有 ...
- linux 监控进程所消耗的资源(内存),达到阈值(绝对值、相对值)后,将其杀死
监控某个python进程是否存在,如不存在则启动 #!/bin/bashwhile [ 1 ]do #打印出当前的jboss进程:grep jboss查询的jboss进程,grep -v " ...
- 滑动窗体的最大值(STL的应用+剑指offer)
滑动窗体的最大值 參与人数:767时间限制:1秒空间限制:32768K 通过比例:21.61% 最佳记录:0 ms|8552K(来自 ) 题目描写叙述 给定一个数组和滑动窗体的大小.找出全部滑动窗体里 ...