矩阵快速幂学习入门
来源:互联网 发布:java 发送邮件 maven 编辑:程序博客网 时间:2024/06/06 05:02
矩阵快速幂的原理是跟普通的快速幂一样,不过原来是数与数相乘,而矩阵快速幂是矩阵与矩阵相乘;
矩阵快速幂是运用于处理一些表达式进行多次递归会超时的问题;难点就是怎样构造矩阵,比如f[ n ] = f[n - 1] + f[ n - 2],
那么构造成的矩阵为:
1 1
1 0;
模板:
typedef struct{ ll a[7][7]; void Init() { memset(a,0,sizeof(0)); for(int i = 1; i < 7; i ++) { a[i][i] = 1; } }}Matrix;Matrix p ={ 1,2,1,4,6,4,1, 1,0,0,0,0,0,0, 0,0,1,4,6,4,1, 0,0,0,1,3,3,1, 0,0,0,0,1,2,1, 0,0,0,0,0,1,1, 0,0,0,0,0,0,1};Matrix Matrix_Mul(Matrix a,Matrix b){ Matrix c; for(int i = 0; i < 7; i ++) { for(int j = 0; j < 7; j ++) { c.a[i][j] = 0; for(int k = 0; k < 7; k ++) { c.a[i][j] += (a.a[i][k] * b.a[k][j]) % MOD; c.a[i][j] %= MOD; } } } return c;}Matrix pow_Matrix(ll m){ Matrix ans,b = p; memset(ans.a,0,sizeof(ans.a)); for(int i = 0; i < 7; i ++) { ans.a[i][i] = 1; } while(m) { if(m & 1) { ans = Matrix_Mul(ans,b); } m >>= 1; b = Matrix_Mul(b,b); } return ans;}
hdu2157
这是裸的矩阵快速幂,给出的图就是要进行相乘的矩阵,
代码:
#include <stdio.h>#include <string.h>#include <algorithm>#include<bits/stdc++.h>typedef long long ll;using namespace std;typedef long long ll;const int maxn = 100 + 10;#define mod 1000struct Matrix{ ll a[maxn][maxn];}origin,res;void Init(ll n){ memset(res.a,0,sizeof(res.a)); for(ll i = 0; i < n ; i ++) { res.a[i][i] = 1; }}Matrix Matrix_multi(Matrix aa,Matrix bb,ll n)//两矩阵相乘的算法{ Matrix ress; memset(ress.a,0,sizeof(ress)); for(ll i = 0; i < n ; i ++) { for(ll j = 0; j < n ; j ++) { for(ll k = 0; k < n ; k ++) { ress.a[i][j] += aa.a[i][k] * bb.a[k][j]; } } } return ress;}void Matrix_calc(ll n,ll k)//矩阵快速幂{ Matrix origins = origin; while(k) { if(k & 1) { res = Matrix_multi(res,origins,n); } origins = Matrix_multi(origins,origins,n); k >>= 1; }}int main(){ int n,m; while( ~ scanf("%d%d",&n,&m) && (n || m) ) { Init(n); memset(origin.a,0,sizeof(origin.a)); for(ll i = 1; i <= m ; i ++) { int x,y; scanf("%d%d",&x,&y); origin.a[x][y] = 1; } int q; scanf("%d",&q); for(ll i = 1; i <= q; i ++) { Init(n); int x,y,k; scanf("%d%d%d",&x,&y,&k); Matrix_calc(n,k); cout << res.a[x][y] % mod <<endl; } } return 0;}
hdu5950 Recursive sequence
题意:f[ n ] = f[n - 1] + 2 * f[n - 2] + n * 4; n的范围< 2^31;
思路:数据范围很大,
首先一看这个题目,很容易想到构造矩阵:那么我们现在来分析一下怎么构造这个矩阵,那么 (n+1)^4 = n^4+4n^3+6n^2+4^n+1 所以光 (n+1)^4 这个矩阵就能构造出 5∗5 的一个矩阵来, 然后 f(n) = f(n−1)+2∗f(n−2) 这个是 2∗2 的矩阵,所以构造出来就应该是 7∗7 的转移矩阵 A :
{f(n),f(n−1),n^4,n^3,n^2,n,1}∗A={f(n+1),f(n),(n+1)^4,(n+1)^3,(n+1)^2,(n+1),1}
然后 f(n+1) = f(n)+2∗f(n−1)+(n+1)4, 可得矩阵 A:
Matrix p =
{
1,2,1,4,6,4,1,
1,0,0,0,0,0,0,
0,0,1,4,6,4,1,
0,0,0,1,3,3,1,
0,0,0,0,1,2,1,
0,0,0,0,0,1,1,
0,0,0,0,0,0,1
};
然后就是直接代码了:
#include<bits/stdc++.h>using namespace std;typedef long long ll;#define MOD 2147493647const int maxn = 200+ 20;typedef struct{ ll a[7][7]; void Init() { memset(a,0,sizeof(0)); for(int i = 1; i < 7; i ++) { a[i][i] = 1; } }}Matrix;Matrix p ={ 1,2,1,4,6,4,1, 1,0,0,0,0,0,0, 0,0,1,4,6,4,1, 0,0,0,1,3,3,1, 0,0,0,0,1,2,1, 0,0,0,0,0,1,1, 0,0,0,0,0,0,1};Matrix Matrix_Mul(Matrix a,Matrix b){ Matrix c; for(int i = 0; i < 7; i ++) { for(int j = 0; j < 7; j ++) { c.a[i][j] = 0; for(int k = 0; k < 7; k ++) { c.a[i][j] += (a.a[i][k] * b.a[k][j]) % MOD; c.a[i][j] %= MOD; } } } return c;}Matrix pow_Matrix(ll m){ Matrix ans,b = p; memset(ans.a,0,sizeof(ans.a)); for(int i = 0; i < 7; i ++) { ans.a[i][i] = 1; } while(m) { if(m & 1) { ans = Matrix_Mul(ans,b); } m >>= 1; b = Matrix_Mul(b,b); } return ans;}int main(){ int Tcase; scanf("%d",&Tcase); for(int ii = 1; ii <= Tcase; ii ++) { ll n,a,b; scanf("%I64d%I64d%I64d",&n,&a,&b); if(n == 1) { cout << a << endl; continue; } if(n == 2) { cout << b << endl; continue; } Matrix ans = pow_Matrix(n - 2); ll anss = 0; anss = (anss + ans.a[0][0] * b % MOD) % MOD; anss = (anss + ans.a[0][1] * a % MOD) % MOD; anss = (anss + ans.a[0][2] * 16 % MOD) % MOD; anss = (anss + ans.a[0][3] * 8 % MOD) % MOD; anss = (anss + ans.a[0][4] * 4 % MOD) % MOD; anss = (anss + ans.a[0][5] * 2 % MOD) % MOD; anss = (anss + ans.a[0][6] * 1 % MOD) % MOD; cout << anss << endl; } return 0;}
0 0
- 矩阵快速幂学习入门
- 矩阵快速幂入门
- 矩阵快速幂(学习)
- 【数论】矩阵快速幂入门
- HDU1575 矩阵快速幂入门
- 矩阵快速幂--学习笔记
- 矩阵快速幂的学习
- 快速幂+快速矩阵幂学习
- hdu1575之矩阵快速幂入门
- hdu1757——矩阵快速幂入门
- 矩阵快速幂入门-斐波拉契数列
- 矩阵快速幂入门 + 求Fibonacci数列
- hdu1575(矩阵快速幂入门题)
- 快速幂学习入门
- 矩阵快速幂专题(矩阵快速幂入门、矩阵构造法、数论规律题)
- 快速幂及矩阵应用(学习)
- 快速矩阵快速幂
- hdu 1575 Tr A(矩阵快速幂入门)
- 安卓 服务(2)
- SylixOS伯克利数据库移植笔记
- thinking in C++
- Java学习笔记
- Ubuntu报“xxx is not in the sudoers file.This incident will be reported” 错误解决方法
- 矩阵快速幂学习入门
- angularjs学习总结 详细教程
- NIO
- 笔记之Day01
- 友元函数
- 怎么样加快JavaScript加载和执行效率
- ScheduledThreadPoolExecutor源码解析
- 一个产品经理的阅读清单
- PHP+MySQL+AJAX+JSON简单实例