A Simple Math Problem(矩阵快速幂(模板))
来源:互联网 发布:数据库insert语句用法 编辑:程序博客网 时间:2024/06/08 08:06
【题目来源】:https://vjudge.net/problem/HDU-1757
【题意】
求解数k对应的f(k)%m,关系式如题面所示。
【思路】
既然给出了递推式,又因为k的取值上限相当大,所以使用矩阵快速幂来实现f(k)的求解。这个时候就可以用到系数矩阵来表示题面给出的关系式。
什么是系数矩阵呢?举个例子(从麻省理工学院线性代数视频上看的):
假如有三个未知数:x,y,z;
存在如下关系:(先不管是否有解)
2x+3y=z
x-y=2z
那么用矩阵表示这个关系的话,如下:
然而呢,这就是一个系数矩阵表示方程组。。
假设定为1,2,3矩阵。
所以呢,对于这道题,我们可以根据第二个关系式来推导系数矩阵,也就是1矩阵,然后把它用快速幂的思想求出系数矩阵的k-9次方,最后呢,再乘以2矩阵,得到3矩阵。
f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)
再上面这个式子里可以得到:
f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)
f(x-1)=1*f(x-1)
f(x-2)=1*f(x-2)
f(x-3)=1*f(x-3)
f(x-4)=1*f(x-4)
f(x-5)=1*f(x-5)
f(x-6)=1*f(x-6)
f(x-7)=1*f(x-7)
f(x-8)=1*f(x-8)
f(x-9)=1*f(x-9)
由此得到系数矩阵(也就是1矩阵):
a0 a1 a2 a3 a4 a5 a6 a7 a8 a9
1_ 0_ 0_ 0_ 0_ 0_ 0_ 0_ 0_ 0_
0_ 1_ 0_ 0_ 0_ 0_ 0_ 0_ 0_ 0_
0_ 0_ 1_ 0_ 0_ 0_ 0_ 0_ 0_ 0_
0_ 0_ 0_ 1_ 0_ 0_ 0_ 0_ 0_ 0_
0_ 0_ 0_ 0_ 1_ 0_ 0_ 0_ 0_ 0_
0_ 0_ 0_ 0_ 0_ 1_ 0_ 0_ 0_ 0_
0_ 0_ 0_ 0_ 0_ 0_ 1_ 0_ 0_ 0_
0_ 0_ 0_ 0_ 0_ 0_ 0_ 1_ 0_ 0_
0_ 0_ 0_ 0_ 0_ 0_ 0_ 0_ 1_ 0_
相对应的2矩阵为:
f(x-1) 0 0 0 0 0 0 0 0 0
f(x-2) 0 0 0 0 0 0 0 0 0
f(x-3) 0 0 0 0 0 0 0 0 0
f(x-4) 0 0 0 0 0 0 0 0 0
f(x-5) 0 0 0 0 0 0 0 0 0
f(x-6) 0 0 0 0 0 0 0 0 0
f(x-7) 0 0 0 0 0 0 0 0 0
f(x-8) 0 0 0 0 0 0 0 0 0
f(x-9) 0 0 0 0 0 0 0 0 0
f(x-10)0 0 0 0 0 0 0 0 0
附:
任何矩阵乘以单位矩阵都等于他本身。下面是5*5的单位矩阵:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1。
然后,。。。。就没然后了。。。
还有千万要记得。。。定义矩阵*运算时,定义一个矩阵之后,要先清零。。。
【代码】
#include<set>#include<map>#include<stack>#include<cmath>#include<queue>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<limits.h>#include<algorithm>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;const int mod=1000000007;typedef unsigned long long ll;typedef long long LL;int k,m;struct mat{ int a[11][11];}ans,temp,base;mat operator*(mat s,mat t){ mat r; mem(r.a,0); for(int i=1; i<=10; i++) { for(int j=1; j<=10; j++) { for(int k=1; k<=10; k++) { r.a[i][j]=r.a[i][j]+s.a[i][k]*t.a[k][j]; if(r.a[i][j]>=m) r.a[i][j]%=m; } } } return r;}void print(mat b){ for(int i=1;i<=10;i++) { for(int j=1;j<=10;j++) printf("%4d ",b.a[i][j]); printf("\n"); }}void init(){ mem(ans.a,0); for(int i=1;i<=10;i++) ans.a[i][i]=1; for(int i=2;i<=10;i++) temp.a[i][i-1]=1; mem(base.a,0); for(int i=1;i<=10;i++) base.a[i][1]=10-i;}int pow_mat(){ init(); while(k) { if(k&1) ans=ans*temp; temp=temp*temp; k>>=1; } ans=ans*base; return ans.a[1][1];}int main(){ while(~scanf("%d%d",&k,&m)) { mem(temp.a,0); for(int i=1; i<=10; i++) scanf("%d",&temp.a[1][i]); if(k<10) printf("%d\n",k%m); else { k-=9; printf("%d\n",pow_mat()); } }}
- A Simple Math Problem(矩阵快速幂(模板))
- HDU 1757 A Simple Math Problem (矩阵快速幂模板)
- hdu - 1757 - A Simple Math Problem(矩阵快速幂)
- hdu 1757 A Simple Math Problem(矩阵快速幂)
- hdu 1757 A Simple Math Problem (矩阵快速幂)
- [HDU 1757] A Simple Math Problem (矩阵快速幂)
- HDU 1757-A Simple Math Problem(矩阵快速幂)
- hdu 1757 A Simple Math Problem(矩阵快速幂)
- HDU 1757 A Simple Math Problem (矩阵快速幂)
- HDU 1757 A Simple Math Problem(矩阵快速幂)
- hdu 1757 A Simple Math Problem(矩阵快速幂)
- HDU 1757 A Simple Math Problem(矩阵快速幂)
- hdu1757-- A Simple Math Problem(矩阵快速幂优化)
- HDU 1757 A Simple Math Problem(矩阵快速幂)
- HDU 1757 A Simple Math Problem (矩阵+快速幂)
- HDU 1757 A Simple Math Problem (矩阵快速幂)
- HDU 1757 A Simple Math Problem (矩阵快速幂)
- HDU 1757 A Simple Math Problem (矩阵快速幂)
- 宽容才能发现美好
- stract2中action中的type中redirectActio,redirectAction,chain的详解
- 第十三周
- JSON
- SQL Server 克隆数据库到同一服务器
- A Simple Math Problem(矩阵快速幂(模板))
- k近邻算法的kd树实现原理
- JSP中9大内置对象详解
- HTML
- oracle 小编程
- Gboard背后的机器学习
- 高矮脉冲数据提取分离,以及连续计数程序结构
- 输入框中数字的增减实现
- win7 下解决python 集成编译环境IDLE无法打开的问题