矩陣快速冪
BY 賴浩瑋
- 矩陣乘法
- 快速冪
what is矩陣快速冪
矩陣乘法
code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define length 3
struct matrix {
long long mat[length][length];
void init(){
memset(mat,0,sizeof(mat));
};
};
matrix mul(matrix a, matrix b)
{
matrix c;
c.init();
for(int j=0 ; j<length ; j++)
{
for(int i=0; i<length ; i++)
{
for(int m=0; m<length ; m++)
{
c.mat[j][i]+=a.mat[j][m]*b.mat[m][i];
}
}
}
return c;
};
int main()
{
matrix a,b;
a.init();
b.init();
for(int i=0; i<length ; i++)for(int j=0 ; j<length ;j++)cin >> a.mat[i][j];
for(int i=0; i<length ; i++)for(int j=0 ; j<length ;j++)cin >> b.mat[i][j];
matrix c = mul(a,b);
for(int i=0 ; i<length ;i++)
{
for(int j=0 ; j<length ; j++)
{
cout << c.mat[i][j] << ' ' ;
}
cout << endl;
}
return 0;
}
簡單來說,我們將a轉換成二進位在做運算就能實現將本來O(n³)的巨無霸變成O(n)的聰明算法
快速冪
- &:確認a是否為2ⁿ的工具
- >>:將二進位表示法右移
工具
我們可以用2ⁿ表示出任何數字,比如說15=1×2⁰+1×2¹+1×2²+1×2³,在將其表述成1111
what is 二進位
- 先將a變成二進位表示
- 檢視他究竟2ⁿ這項是不是有存在
- 如果有就將他乘上去
做法
#include <bits/stdc++.h>
using namespace std;
int main() {
int n,a;
int ans=1;
cin >> a >> n;
while(n > 0)
{
if(n & 1==1) ans=(ans*a);
n = n >> 1;
a=(a*a);
}
cout << ans <<endl;
return 0;
}
code
我們可以用費氏數列舉例
what is 矩陣快速冪
矩陣+快速冪
- 費氏數列是由義大利數學家費波那契所提出的一串數字,聽說很神奇(?
何謂費氏數列
f(n) = f(n-2) + f(n-1)
遞迴式
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define length 2
struct matrix
{
ll mat[2][2];
};
struct matrix mul(struct matrix A, struct matrix B)
{
struct matrix C;
C.mat[0][0]=C.mat[0][1]=C.mat[1][0]=C.mat[1][1]=0;
for (int i=0; i<length; i++)
for (int j=0; j<length; j++)
for (int k=0; k<length; k++)
C.mat[i][j]+=A.mat[i][k]*B.mat[k][j];
return C;
}
struct matrix fastPow(struct matrix A, int n)
{
struct matrix I; // identity matrix
I.mat[0][0]=I.mat[1][1]=1;
I.mat[0][1]=I.mat[1][0]=0;
while (n!=0)
{
if (n&1)
{
I=mul(I, A);
}
A=mul(A, A);
n>>=1;
}
return I;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int n=0;
while (cin >> n)
{
struct matrix A; // A: {[0, 1], [1, 1]}
struct matrix B; // B: {[0, not used], [1, not used]}
A.mat[0][0]=0;
A.mat[0][1]=1;
A.mat[1][0]=1;
A.mat[1][1]=1;
B.mat[0][0]=0; // f0
B.mat[0][1]=0;
B.mat[1][0]=1; // f1
B.mat[1][1]=0;
struct matrix ans;
ans=fastPow(A, n);
cout << ans.mat[1][0] << endl;
}
return 0;
}
社展
By howwei