快速幂(取模)

详解:http://blog.csdn.net/lsldd/article/details/5506933

原理:

直接乘要做998次乘法。但事实上可以这样做,先求出2^k次幂:

3 ^ 2 = 3 * 3
3 ^ 4 = (3 ^ 2) * (3 ^ 2)
3 ^ 8 = (3 ^ 4) * (3 ^ 4)
3 ^ 16 = (3 ^ 8) * (3 ^ 8)
3 ^ 32 = (3 ^ 16) * (3 ^ 16)
3 ^ 64 = (3 ^ 32) * (3 ^ 32)
3 ^ 128 = (3 ^ 64) * (3 ^ 64)
3 ^ 256 = (3 ^ 128) * (3 ^ 128)
3 ^ 512 = (3 ^ 256) * (3 ^ 256)

再相乘:

3 ^ 999
= 3 ^ (512 + 256 + 128 + 64 + 32 + 4 + 2 + 1)
= (3 ^ 512) * (3 ^ 256) * (3 ^ 128) * (3 ^ 64) * (3 ^ 32) * (3 ^ 4) * (3 ^ 2) * 3

 

 1 #include <stdio.h>
 2 int qpow(int a,int b)   //递归快速幂 
 3 {
 4     int tem = 1;
 5     if (b == 0) return 1;
 6     else if(b == 1) return a;
 7     tem = qpow(a,b>>1);
 8     tem = tem*tem;
 9     if (b&1) tem *= a;   
10     return tem;
11 }
12 int qpow2(int a,int b,int n)   //递归快速幂取模 
13 {
14     int tem = 1;
15     if (b == 0) return 1;
16     else if(b == 1) return a%n;
17     tem = qpow2(a,b>>1,n);
18     tem = tem*tem%n;
19     if (b&1) tem = tem*a%n;   
20     return tem;
21 }
22 int qpow1(int a,int b)  //循环快速幂 
23 {
24     int tem = 1,ret = a;
25     while (b > 0)
26     {
27         if (b&1) tem = tem*ret;
28         ret = ret*ret;
29         b >>= 1;
30     }    
31     return tem;
32 } 
33 int main ()
34 {
35     int a,b,n;
36     while (scanf("%d%d",&a,&b)!=EOF)
37     {
38         scanf("%d",&n);
39         printf("递归快速幂--%d\n",qpow(a,b)); 
40         printf("循环快速幂--%d\n",qpow1(a,b));
41         printf("循环快速幂--%d\n",qpow2(a,b,n));
42     }
43     return 0;
44 }

 

posted @ 2016-12-05 12:49  gaoyanliang  阅读(358)  评论(0编辑  收藏  举报