与快速幂一样,可以将递推式通过二进制的方式来进行优化,这个学了快速幂就是十分容易理解

大概的板子如下:

struct mat///自己定义大小的矩阵
{ll m[11][11];
};
mat mulmat(mat A,mat B)///两个矩阵相乘
{mat C;memset(C.m,0,sizeof(C.m));for(int i=0;i<n;i++)///注意n是自己构造矩阵的大小for(int j=0;j<n;j++)for(int k=0;k<n;k++)C.m[i][j]=(C.m[i][j]+A.m[i][k]*B.m[k][j])%mod;return C;
}
mat qmod_mat(mat A,ll b)///A为变换矩阵,b为幂
{mat ans;memset(ans.m,0,sizeof(ans.m));for(int i=0;i<10;i++) ans.m[0][i]=i;///给自己的初始矩阵赋值,一般初始矩阵和变换矩阵都是固定的while(b){if(b&1) ans=mulmat(ans,A);A=mulmat(A,A);b>>=1;}return ans;///最后的矩阵,答案
}
int main()

这个与快速幂写法略有不同,主要是因为矩阵快速幂需要自己构造你的变换函数,而快速幂的a仅仅是一个底数。

构造矩阵快速幂的方法是这种题的重要难点:

矩阵构造方法

Fibonacci数列:F(0)=1 , F(1)=1 , F(n)=F(n-1)+F(n-2)

我们以前快速求Fibonacci数列第n项的方法是 构造常系数矩阵

(一)   Fibonacci数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的第n项快速求法(不考虑高精度)

解法:

考虑1×2的矩阵【f[n-2],f[n-1]】。根据Fibonacci数列的递推关系,我们可以通过乘以一个2×2的矩阵A,得到矩阵:【f[n-1],f[n]】。

即:【f[n-2],f[n-1]】*A = 【f[n-1],f[n]】=【f[n-1],f[n-1]+f[n-2]】

很容易构造出这个2×2矩阵A,即:
0 1 
1 1

所以,有【f[1],f[2]】×A=【f[2],f[3]】
又因为矩阵乘法满足结合律,故有:
【f[1],f[2]】×A ^(n-1) =【f[n],f[n+1]】
这个矩阵的第一个元素f[n]即为所求。

(二)   数列f[n]=f[n-1]+f[n-2]+1,f[1]=f[2]=1的第n项的快速求法(不考虑高精度)

解法:
仿照前例,考虑1×3的矩阵【f[n-2],f[n-1],1】,希望求得某3×3的矩阵A,使得此1×3的矩阵乘以A得到矩阵:【f[n-1],f[n],1】

即:【f[n-2],f[n-1],1】* A =【f[n-1],f[n],1】=【f[n-1],f[n-1]+f[n-2]+1,1】

容易构造出这个3×3的矩阵A,即:
0 1 0 
1 1 0 
0 1 1

故:【f[1],f[2],1】* A^(n-1) = 【f[n],f[n+1],1】

(三)数列f[n]=f[n-1]+f[n-2]+n+1,f[1]=f[2]=1的第n项的快速求法(不考虑高精度).
解法:
仿照前例,考虑1×4的矩阵【f[n-2],f[n-1],n,1】,希望求得某4×4的矩阵A,使得此1×4的矩阵乘以A得到矩阵:【f[n-1],f[n],n+1,1】
即:【f[n-2],f[n-1],n,1】* A  = 【f[n-1],f[n],n+1,1】=【f[n-1],f[n-1]+f[n-2]+n+1,n+1,1】
容易构造出这个4×4的矩阵A,即:
0 1 0 0 
1 1 0 0 
0 1 1 0 
0 1 1 1

故:【f[1],f[2],3,1】* A^(n-1) = 【f[n],f[n+1],n+2,1】

(四)   数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的前n项和s[n]=f[1]+f[2]+……+f[n]的快速求法(不考虑高精度).

解法:

仿照之前的思路,考虑1×3的矩阵【f[n-2],f[n-1],s[n-2]】,我们希望通过乘以一个3×3的矩阵A,得到1×3的矩阵:【f[n-1],f[n],s[n-1]】
即:【f[n-2],f[n-1],s[n-2]】 * A  = 【f[n-1],f[n],s[n-1]】=【f[n-1],f[n-1]+f[n-2],s[n-2]+f[n-1]】
容易得到这个3×3的矩阵A是:
0 1 0 
1 1 1 
0 0 1

这种方法的矩阵规模是(r+1)*(r+1)

f(1)=f(2)=s(1)=1 ,所以,有

【f(1),f(2),s(1)】* A  = 【f(2),f(3),s(2)】

故:【f(1),f(2),s(1)】* A^(n-1)  = 【f(n),f(n+1),s(n)】

(五)   数列f[n]=f[n-1]+f[n-2]+n+1,f[1]=f[2]=1的前n项和s[n]=f[1]+f[2]+……+f[n]的快速求法(不考虑高精度).

解法:

考虑1×5的矩阵【f[n-2],f[n-1],s[n-2],n,1】,
我们需要找到一个5×5的矩阵A,使得它乘以A得到如下1×5的矩阵【f[n-1],f[n],s[n-1],n+1,1】
即:【f[n-2],f[n-1],s[n-2],n,1】* A  =【f[n-1],f[n],s[n-1],n+1,1】

=【f[n-1], f[n-1]+f[n-2]+n+1,s[n-2]+f[n-1],n+1,1】
容易构造出A为:
0 1 0 0 0 
1 1 1 0 0 
0 0 1 0 0 
0 1 0 1 0 
0 1 0 1 1

故:【f(1),f(2),s(1),3,1】* A^(n-1)  = 【f(n),f(n+1),s(n),n+2,1】

一般地,如果有f[n]=p*f[n-1]+q*f[n-2]+r*n+s
可以构造矩阵A为:
0  q  0  0  0 
1  p  1  0  0 
0  0  1  0  0 
0  r  0  1  0 
0  s  0  1  1

更一般的,对于f[n]=Sigma(a[n-i]*f[n-i])+Poly(n),其中0<i<=某常数c, Poly (n)表示n的多项式,我们依然可以构造类似的矩阵A来解决问题。
设Degree(Poly(n))=d, 并规定Poly(n)=0时,d=-1,此时对应于常系数线性齐次递推关系。则本方法求前n项和的复杂度为:
((c+1)+(d+1))3*logns

例如:A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N >= 2);给定三个值N,X,Y求S(N):S(N) = A(0)2 +A(1)2+……+A(n)2。

解:考虑1*4 的矩阵【s[n-2],a[n-1]^2,a[n-2]^2,a[n-1]*a[n-2]】

我们需要找到一个4×4的矩阵A,使得它乘以A得到1×4的矩阵

【s[n-1],a[n]^2,a[n-1]^2,a[n]*a[n-1]】

即:【s[n-2],a[n-1]^2,a[n-2]^2,a[n-1]*a[n-2]】* A = 【s[n-1],a[n]^2,a[n-1]^2,a[n]*a[n-1]】

= 【s[n-2]+a[n-1]^2 , x^2 * a[n-1]^2 + y^2 * a[n-2]^2 + 2*x*y*a[n-1]*a[n-2] ,

a[n-1]^2 , x*a[n-1]^2 + y*a[n-2]a[n-1]】

可以构造矩阵A为:

1     0    0    0

1    x^2   1    x

0    y^2   0    0

0    2xy   0    y

故:【S[0],a[1]^2,a[0]^2,a[1]*a[0]】 * A^(n-1) = 【s[n-1],a[n]^2,a[n-1]^2,a[n]*a[n-1]】

所以:【S[0],a[1]^2,a[0]^2,a[1]*a[0]】 * A^(n) = 【s[n],a[n+1]^2,a[n]^2,a[n+1]*a[n]】

若A = (B * C ) 则AT = ( B * C )T = CT * BT

附:大佬博客链接

矩阵快速幂+构造方法相关推荐

  1. 矩阵快速幂(Matrix_Fast_Power)

    一.基础知识 (1)矩阵乘法 https://blog.csdn.net/weixin_43272781/article/details/82899737 简单的说矩阵就是二维数组,数存在里面,矩阵乘 ...

  2. 矩阵快速幂(教主传授)

    教主传授 快速幂的思想: 假设我们要求a^b,最朴素的方法就是不断地乘a,乘b次,复杂度O(b). 如果b很大,10^9,就需要用快速幂的思想. 例:a=3,b=100: 100的二进制为:11001 ...

  3. 【做题】SRM701 Div1 Hard - FibonacciStringSum——数学和式&矩阵快速幂

    原文链接 https://www.cnblogs.com/cly-none/p/SRM701Div1C.html 题意:定义"Fibonacci string"为没有连续1的01串 ...

  4. 快速幂 + 矩阵快速幂

    快速幂 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #define LL lo ...

  5. HDU4549(矩阵快速幂+快速幂)

    f(n)=a^f(n-1) + b^f(n-2):计算矩阵部分用矩阵快速幂:计算a的幂次和b的幂次用快速幂. #include<iostream> #include<algorith ...

  6. [HNOI2008]GT考试[矩阵快速幂+kmp优化的dp]

    解题思路:假如说我们用f[i]表示长度为i的串能组合成无不吉利数字的组合的个数的话我们无法找到f[i]和f[i+1]的关系,就是我们下一位填某个数字会不会出现不吉利串,这就和你前面的串末尾于不吉利串重 ...

  7. I-Matrix Power Series POJ - 3233 矩阵快速幂+分治

    I-Matrix Power Series POJ - 3233 矩阵快速幂+分治 Problem Description Given a n × n matrix A and a positive ...

  8. H - Fibonacci POJ - 3070 (矩阵快速幂)

    H - Fibonacci POJ - 3070 (矩阵快速幂) Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and ...

  9. HDU 6185 Covering 矩阵快速幂 递推

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6185 题目描述: 一个4*n的矩形, 你用1*2的矩形覆盖有多少种方案, n <= 1e18 ...

最新文章

  1. 基于kryo序列化方案的memcached-session-manager多memcached...
  2. sigprocmask和sigsuspend转
  3. 黑莓blackberry手机刷ROM 的详细教程
  4. H3C TFTP操作示例
  5. 【SpringMVC入门】SpringMVC环境搭建、接收参数的几种方式、视图解析器、@ResponseBody
  6. ecshop在首页调用dedecms文章
  7. 十 web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令
  8. android 7.0 解锁亮屏,Android7.0亮屏流程分析
  9. C语言定义直线的数据类型,C语言 | 数据类型
  10. python使用如下方法规范化数组_python归一化多维数组的方法
  11. Oracle 学习笔记二 Create table
  12. 安卓是java ios c_如何为Android和iOS使用相同的C ++代码?
  13. 查询语句的练习45道题
  14. 大数据之-入门_大数据发展前景---大数据之hadoop工作笔记0005
  15. Linux下的磁盘分区与加密
  16. 句柄泄漏与应用程序体验查找服务(AELookupSvc)
  17. dncnn图像去噪_基于强化学习的图像去噪方法与流程
  18. Java调用WebService接口
  19. Unity 材质之_stander shader
  20. oracle新增字段排序,oracle指定排序的方法详解

热门文章

  1. Android OpenCV 边缘检测 Canny 的使用
  2. haystack全文检索框架
  3. Linux 忘记登录密码?破解系统登陆密码
  4. golang 同一个包中函数互相调用报错 undefined 以及在 VSCode 中配置右键执行整个包文件
  5. LaTeX技巧 twocolumn 双栏
  6. 用java向mysql数据库中插入数据为空
  7. 与jQuery的感情碰撞——由浅入深学jQuery
  8. Gazebo构建小车模型并通过ROS控制
  9. C++ static
  10. 图像特征点—SIFT特征点