算法疑难(c++实现)---1、快速幂

算法疑难(c++实现)---1、快速幂

一、总结

一句话总结:

比如在求a^11的时候,快速幂就是利用11的二进制1011,也即11=2º×1+2¹×1+2²×0+2³×1=1+2+8,将a^11转化为a^1*a^2*a^8,从而用O(logn)的时间复杂度求解
#include <iostream>
using namespace std;

int pow(int a,int n){
   int ans=1,base=a;
   while(n){
       if(n%2==1) ans=ans*base;
       base=base*base;
       n=n/2;
   }
   return ans;
}

int main(){
    cout<<pow(2,22)<<endl;
    return 0;
}

1、快速幂取模的原理?

根据同余定理,我们知道,(a*b)%m=((a%m)*(b%m))%m;其实快速幂取模也是用到这个
#include <iostream>
using namespace std;

const int mod=10007;

int pow(int a,int n){
   int ans=1,base=a%mod;
   while(n){
       if(n%2==1) ans=(ans*base)%mod;
       base=(base*base)%mod;
       n=n/2;
   }
   return ans;
}

int main(){
    cout<<pow(2,110)<<endl;
    return 0;
}

二、快速幂

博客对应课程的视频位置:1、快速幂
https://www.fanrenyi.com/video/30/280

1、朴素求法

 1 /*
 2 最朴素的求幂方法
 3 也就是平常使用pow函数,最简单的实现就是一直累乘
 4 
 5 比如求a^n
 6 
 7 */
 8 #include <iostream>
 9 using namespace std;
10 
11 int pow(int a,int n){
12    int ans=1;
13    for(int i=1;i<=n;i++){
14        ans*=a;
15    } 
16    return ans;
17 }
18 
19 int main(){
20     cout<<pow(2,22)<<endl;
21     return 0;
22 }
23 
24 /*
25 
26 可以看到,算法的时间复杂度是O(n)。为了降低时间复杂度,
27 我们可以使用快速幂算法,
28 将时间复杂度降低到O(logn)。
29 
30 */

2、快速幂

 1 /*
 2 
 3 快速幂:
 4 
 5 首先,快速幂的目的就是做到快速求幂,
 6 
 7 假设我们要求a^n,那么其实n是可以拆成二进制的,
 8 例如当n==11时
 9 11的二进制是1011,
10 11 =2º×1+2¹×1+2²×0+2³×1=1+2+8,
11 所以
12 a^11=a^1*a^2*a^8
13 原来算11次,现在只需要算三次
14 
15 具体怎么算呢:
16 我们可以用一个变量base来在每次循环的时候记录a^i,
17 最开始base是a
18 然后每次循环让base=base*base
19 那么base的值
20 a-->a^2-->a^4-->a^8-->a^16-->a^32.......
21 然后根据11的二进制,1011,
22 取位为1时候的base值即可,
23 也就是取a,a^2,a^8
24 
25 由此可以得到代码:
26 
27 
28 */
29 
30 #include <iostream>
31 using namespace std;
32 
33 int pow(int a,int n){
34    int ans=1,base=a;
35    while(n){
36        if(n%2==1) ans=ans*base;
37        base=base*base;
38        n=n/2;
39    }
40    return ans;
41 }
42 
43 int main(){
44     cout<<pow(2,22)<<endl;
45     return 0;
46 }
47 
48 
49 
50 /*
51 
52 n 11
53 ans a
54 base a^2
55 
56 n 5
57 ans a*a^2
58 base a^2*a^2=a^4
59 
60 n 2
61 ans a*a^2
62 base a^4*a^4=a^8
63 
64 n 1
65 ans a*a^2*a^8
66 base a^8*a^8=a^16
67 
68 n 0
69 
70 */

3、快速幂求模

 1 /*
 2 因为求幂运算得到的结果一般很大
 3 所以一般需要对求幂的结果进行取模
 4 所以下面就来说说快速幂取模的操作
 5 
 6 根据同余定理,我们知道
 7 (a*b)%m = ((a%m)*(b%m))%m;
 8 其实快速幂取模也是用到这个
 9 
10 
11 */
12 
13 #include <iostream>
14 using namespace std;
15 
16 const int mod=10007;
17 
18 int pow(int a,int n){
19    int ans=1,base=a%mod;
20    while(n){
21        if(n%2==1) ans=(ans*base)%mod;
22        base=(base*base)%mod;
23        n=n/2;
24    }
25    return ans;
26 }
27 
28 int main(){
29     cout<<pow(2,110)<<endl;
30     return 0;
31 }
 
原文地址:https://www.cnblogs.com/Renyi-Fan/p/13064188.html