首页 > 其他 > 详细

快速幂

时间:2014-09-22 23:11:54      阅读:399      评论:0      收藏:0      [点我收藏+]

  第一篇博文,讲一点简单的内容吧。

  快速幂在很多比赛中都是非常常见的题目。当然,我们必须在很短的时间内解决这样的“代码”

  

  下面我们就来考虑一下快速幂基于什么样的原理?

  1、二分法

  对于任意的 x * y 都有 x % n * y % n (注意 xk != xk % n

  所以 xk = xk / 2 * xk / 2 % n(k % 2 == 0 若 k % 2 == 1 就 多乘上一个 x 即可)

  所以 我们不难想出如下的代码

  

 1 #include<cstdlib>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int a,b,c;
 6 int fast_mod(int a,int b,int c)
 7 {
 8       if(b == 0) return 1;
 9       int t = fast_mod(a,b/2,c);       
10       if(b % 2)
11           return t * t  % c * a % c;
12       else
13           return t * t % c;        
14 }
15 int main()
16 {
17       scanf("%d %d %d",&a,&b,&c); // a ^ b % c
18       printf("%d",fast_mod(a,b,c));
19       return 0;
20 }

 2、倍增法

  倍增法是基于位运算的一种快速幂的求法,一般利用迭代实现,常数比二分更优。其算法原理如下:

  我们知道a^(p+q) = a^p*a^q;

  所以,我们可以提前算出a^(2^i)(下面程序中how数组)的值,每次通过位运算来得出结果,最后相乘。

  举个例子把:8 ^ 5 mod 9,5 = 101(2);

  所以,左边 = (8 ^ 1 mod 9)*(8 ^ (1<<2) mod 9)

  代码如下:

  

 1 #include<cstdio>
 2 #include<cstdlib>
 3 using namespace std;
 4 long long a,b,c;
 5 long long how[64];    //倍增数组
 6 
 7 void deal()        //预处理出倍增数组:how[i] = a^(2^i)%c
 8 {
 9     int i = 0;
10     how[i] = a%c;
11     for (i = 1;i<64;i++)
12         how[i] = how[i-1]*how[i-1]%c;
13 }
14 
15 long long quick(long long a,long long b,long long c)
16 {
17     int i = 0,ret = 1;
18     while (b)
19     {
20         if (b & 1)
21             ret = (ret*how[i])%c;
22         b >>= 1;
23         i++;
24     }
25     return ret;
26 }
27 
28 int main()
29 {
30     freopen("test.in","r",stdin);
31     freopen("test.out","w",stdout);
32     scanf("%I64d %I64d %I64d",&a,&b,&c);
33     deal();
34     printf("%I64d",quick(a,b,c));
35     return 0;
36 }

 

快速幂

原文:http://www.cnblogs.com/RHX-LMY/p/3986834.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!