快速幂

上周在牛客做了一道快速幂的题,今天整理一下,参考了睛神的《算法笔记》。

一、用处:

  给定三个正整数a,b,m,计算$a^b%p$,时间复杂度O(logb);

二、原理:

  形如$a^b$,

    1.若b为偶数,可分解为$a^{\frac{b}{2}}*a^{\frac{b}{2}}$ 或 $(a^{2})^{\frac{b}{2}}$;

    2.若b为奇数,可分解为$a^{\frac{b}{2}}*a^{\frac{b}{2}}*a$;  

  由此可以使用递归或者迭代计算。

三、实现:

  1.递归计算,一直分解直到b为0时返回1,回溯得到结果,层数为logn;

1 typedef long long ll
2 ll binary_pow(ll a,ll b,ll p) {
3     if(b==0)    return 1;
4     if(b&1) return a*binary_pow(a,b-1,p)%p;
5     else {
6         ll t=binary_pow(a,b/2,p);        //细节
7         return t*t%p;
8     }
9 }

  细节:如果 直接返回binary_pow(a,b/2,p)*binary_pow(a,b/2,p)%p; 需要做两次递归,降低了效率;而先赋值的方法则只进行一次递归。

 

  2.迭代计算,将b反复折半到1,同时a反复平方,期间若b为奇数,则将当时的a累乘起来(相当于b-1),将其与最后b为1时的a相乘即为结果。

 1 typedef long long ll;
 2 ll binary_pow(ll a,ll b,ll p){
 3     ll t=1;
 4     while(b>0){
 5         if(b&1) t=t*a%p;
 6         a=(a%p)*(a%p)%p;    //怕数据太大可以多取模几次
 7         b>>=1;
 8     }
 9     return t;
10 }

 

posted @ 2019-09-06 12:59 时侍 阅读(...) 评论(...) 编辑 收藏