快速幂,矩阵乘法,矩阵快速幂
快速幂利用二进制
复杂度 log级
#include <cstdio> #include <iostream> #include <string> #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; int q_power(int a,int b,int c) { int r=1; a%=c; while (b) { if (b&1) { r=(r*a)%c; } a=(a*a)%c; b>>=1; } return r; } int a,b,c; int main () { cin>>a>>b>>c; cout<<q_power(a,b,c); return 0; }
附带上矩阵快速幂以及
矩阵快速幂求斐波那契数列:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int mod = 10000; const int maxn = 35; int N; struct Matrix { int mat[maxn][maxn]; int x, y; Matrix() { memset(mat, 0, sizeof(mat)); for (int i = 1; i <= maxn - 5; i++) mat[i][i] = 1; } }; inline void mat_mul(Matrix a, Matrix b, Matrix &c) { memset(c.mat, 0, sizeof(c.mat)); c.x = a.x; c.y = b.y; for (int i = 1; i <= c.x; i++) { for (int j = 1; j <= c.y; j++) { for (int k = 1; k <= a.y; k++) { c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod; c.mat[i][j] %= mod; } } } return ; } inline void mat_pow(Matrix &a, int z) { Matrix ans, base = a; ans.x = a.x; ans.y = a.y; while (z) { if (z & 1 == 1) mat_mul(ans, base, ans); mat_mul(base, base, base); z >>= 1; } a = ans; } int main() { while (cin >> N) { switch (N) { case -1: return 0; case 0: cout << "0" << endl; continue; case 1: cout << "1" << endl; continue; case 2: cout << "1" << endl; continue; } Matrix A, B; A.x = 2; A.y = 2; A.mat[1][1] = 1; A.mat[1][2] = 1; A.mat[2][1] = 1; A.mat[2][2] = 0; B.x = 2; B.y = 1; B.mat[1][1] = 1; B.mat[2][1] = 1; mat_pow(A, N - 1); mat_mul(A, B, B); cout << B.mat[1][1] << endl; } return 0; }
顺便来一发
矩阵乘法:
/* 假设 A 是 m*p 的矩阵 , B 是 p*n 的矩阵 记 C = AB (C 是 矩阵 A与B的乘积) 那么 C 是 m*n 的矩阵 */ for (int i = 1;i <= m;++i)//A的行 { for (int j = 1;j <= n;++j)//B的列 { for (int k = 1;k <= p;++k)//通过公式求C { C[i][j] += A[i][k]*B[k][j]; } } }
#include<iostream> #include<cmath> #include<cstring> using namespace std; typedef long long LL; const LL mod = 1000000007; /* 矩阵快速幂求斐波那契数列 输入 n 输出 f[n] */ struct Mat { LL mat[2][2]; }; Mat operator * (Mat a,Mat b)//矩阵乘法 { Mat c; for (int i = 0;i < 2;++i) { for (int j = 0;j < 2;++j) { c.mat[i][j] = 0; for (int k = 0;k < 2;++k) { c.mat[i][j] = ((a.mat[i][k]*b.mat[k][j])%mod + c.mat[i][j])%mod; } } } return c; } Mat operator ^ (Mat a,LL k)//矩阵幂 { Mat c; for (int i = 0;i < 2;++i) { for (int j = 0;j < 2;++j) { c.mat[i][j] = (i==j);//初始化为单位矩阵 } } //据说任何矩阵乘以单位矩阵其值不会变 for (;k;k>>=1) { if (k&1) c = c*a; a = a*a; } return c; } int main() { LL n; while (cin>>n) { Mat a; a.mat[0][0] = 1,a.mat[0][1] = 1,a.mat[1][0] = 1,a.mat[1][1] = 0; Mat fn = a^n; cout<<fn.mat[0][1]<<endl; } return 0; }