数论--快速幂,矩阵快速幂

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.矩阵快速幂:

 

以上是关于数论--快速幂,矩阵快速幂的主要内容,如果未能解决你的问题,请参考以下文章

矩阵快速幂专题

cf 450b 矩阵快速幂(数论取模 一大坑点啊)

HDU 2256 Problem of Precision 数论矩阵快速幂

数论——快速幂,模运算及快速幂求逆元

Matrix Power Series - 矩阵快速幂对分块矩阵加速

Matrix Power Series - 矩阵快速幂对分块矩阵加速