数论--快速幂,矩阵快速幂
Posted 东流vip
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论--快速幂,矩阵快速幂相关的知识,希望对你有一定的参考价值。
1.快速幂:
当求a的b次方的时候,我们可以写一个函数一次循环求出,又可以用math文件里面的pow(double a,double b)解决
但是,当b非常大还要取模呢?O(n)的时间复杂度也不行怎么办?
可以用快速幂的方法:
要求a^b时,那么其实b是可以拆成二进制的,该二进制数第i位的权为2^(i-1),例如当b==11时
a^11=a^(2^0+2^1+2^3)=a^(2^0)*a^(2^1)*a^(2^3)
实现时要用到位运算:
b&1是取b二进制的末尾
b>>1是去掉b二进制的末尾
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 5 #define ll long long 6 7 ll pow_mod(ll a,ll b,ll p) //(a^b)%p 8 { 9 ll ans=1; 10 while(b) 11 { 12 if(b&1) 13 { 14 ans=(ans*a)%p; 15 } 16 a=(a*a)%p; 17 b>>=1; 18 } 19 return ans; 20 } 21 22 23 int main() 24 { 25 ll a,b,p; 26 cin>>a>>b>>p; 27 cout<<pow_mod(a,b,p)<<endl; 28 }
其中,a=(a*a)%p理解起来就是:第0次a=a^(2^0);//初始值 ,第一次a=a*a相当于a^(2^1),第二次相当于a^(2^2).......a^(2^n),再结合上面a^11=a^1011(二进制)=a^(2^0)*a^(2^1)*a^(2^3),
对应的就是,在第0次,第1次,第3次的时候,ans=(ans*a)%p;
而在第0次,第1次,第3次的时候ans要更新,是因为11的二进制1011的第0位,第1位,第3位是1(即if(b&1),当前b的末尾是1)
讲解over,例题POJ 1995
2.矩阵快速幂:
以上是关于数论--快速幂,矩阵快速幂的主要内容,如果未能解决你的问题,请参考以下文章
HDU 2256 Problem of Precision 数论矩阵快速幂