快速幂计算(整数快速幂/矩阵快速幂)
//*************快速幂计算****************************************
朴素算法实现:
1 ll get_pow(ll x, ll n) //** (这里的n要求不小于0,如果n小于0则令n=-n,并且最终返回1.0/ans即可) 2 { 3 ll ans=1; 4 while(n--) 5 { 6 ans*=x%MAX; 7 ans%=MAX; 8 } 9 return ans; 10 }
快速幂算法:
原理:
二分:
假设我们现在要计算pow(x,n),那么有当n为偶数时pow(x, n)==pow(x*x, n/2),当n为奇数时,pow(x, n)==pow(x, n-1)*x, 此时n-1为偶数,可按前面的公式继续迭代;
循环往复,即可计算出答案;
二进制:
计算pow(x,n),先将n转化为二进制形式,n=2^a+2^b....
例如:计算pow(x,21),19=2^4+2^2+2^1;其中2^2可以由(2^1)*(2^1)得到,同理, 2^4可以由(2^2)*(2^2)得到;
所有有pow(x,21)==x^(2^4+2^2+2^1),其时间复杂度为o(long2(n));
以上两种思路的出发点不同,不过其本质一致,代码也相同;
代码:
1 ll get_pow(ll x, ll n) //** (这里的n要求不小于0,如果n小于0则令n=-n,并且最终返回1.0/ans即可) 2 { 3 int ans=1; 4 while(n) 5 { 6 if(n&1) 7 { 8 ans=(ans*x)%MAX; 9 } 10 x=(x*x)%MAX; 11 n>>=1; 12 } 13 return ans; 14 }
//*********************矩阵快速幂计算**********************************
矩阵快速幂和快速幂算法原理一样,只是操作对象换成了矩阵;
http://acm.nyist.net/JudgeOnline/problem.php?pid=148(题目链接)
ac代码:
1 #include <bits/stdc++.h> 2 #define MAXN 2 3 #define mod 10000 4 #define ll long long 5 using namespace std; 6 7 struct Matrix 8 { 9 ll x[MAXN][MAXN]; 10 }; 11 12 Matrix temp={1, 1, 1, 0}; 13 14 ll n; //***n为幂数,结果对mod取模 15 16 Matrix multi(Matrix a, Matrix b) //***矩阵乘法 17 { 18 Matrix c; 19 memset(c.x, 0, sizeof(c.x)); 20 for(int i=0; i<MAXN; i++) 21 { 22 for(int j=0; j<MAXN; j++) 23 { 24 for(int k=0; k<MAXN; k++) 25 { 26 c.x[i][j]+=(a.x[i][k]*b.x[k][j])%mod; 27 } 28 } 29 } 30 return c; 31 } 32 33 ll Pow(ll n) 34 { 35 Matrix ans; 36 temp.x[0][0]=temp.x[0][1]=temp.x[1][0]=1; 37 temp.x[1][1]=0; 38 memset(ans.x, 0, sizeof(ans.x)); 39 ans.x[0][0]=ans.x[1][1]=1; 40 while(n) 41 { 42 if(n&1) ans=multi(ans, temp); 43 temp=multi(temp, temp); 44 n>>=1; 45 } 46 return ans.x[0][1]; 47 } 48 49 int main(void) 50 { 51 std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); 52 while(cin >> n && n!=-1) 53 { 54 cout << Pow(n)%mod << endl; 55 } 56 return 0; 57 }
我就是我,颜色不一样的烟火 --- geloutingyu