随笔 - 28, 文章 - 0, 评论 - 0, 阅读 - 22691

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

快速幂算法

Posted on   POOH1DROSE  阅读(616)  评论(0编辑  收藏  举报

在计算形如ab的运算时,如果用朴素的算法需要O(b)的时间复杂度,当b很大时显然是不可取的,于是我们希望找到一种快速的算法来计算,尤其是题目中要求答案取模时。

对于朴素的算法我们有

ans=1;

for(int i=1;i<=b;i++) (ans*=a)%=mod;

我们可以简单优化一下,在循环之前加入a%=mod;

 

当b为偶数时我们可以这样

int ans=1;

a%=mod;

(a*=a)%=mod;

for(int i=1;i<=b/2;i++)

{

(ans*=a)%=mod;

}

当b为奇数时需要特判

int ans=1;

a%=mod;

if(b&1) ans*=a;

(a*=a)%=mod;

for(int i=1;i<=b/2;i++)

{

(ans*=a)%=mod;

}

这样做可以将时间减半。

 

我们甚至可以这样

int ans=1;

a%=mod;

if(b&1) ans*=a;

(a*=a)%=mod;

b/=2;

if(b&1) (ans*=a)%=mod;

(a*=a)%=mod;

b/=2;

for(int i=1;i<=b;i++) (ans*=a)%=mod;

 

那么我们自然会想到,如果时间可以减半,减半,再减半,那么时间复杂度可以降到O(log n).

实现方法也很简单,就是把上述步骤迭代多次。

代码如下:

 

复制代码
int ans=1;
a%=mod;
while(b)
{
    if(b&1) (ans*=a)%=mod;
    b/=2;//可以知道任何一个大于1的数经历多次这步均可以达到b=1,所以不用担心ans最后得不到a的值
    (a*=a)%=mod;
} 
View Code
复制代码

 

典型例题:NOIP201305转圈游戏

点击右上角即可分享
微信分享提示