快速幂算法

一:用处:

1.顾名思义,即快速计算幂。对于普通的pow函数,时间复杂度为O(n),因为有n个自身相乘嘛,但是对于快速幂呢,他可以将复杂度降为logn,快好多,这个logn咋算的呢,我没仔细想过,博主太菜了,见谅。

2.对于一个幂算出来极大的数,for example:2^200,这样的数,明显没办法用 long long /int来存放,假如要将该数对一个数取模,势必用到字符串操作方式,想想都麻烦,更别说敲代码了,再者,假如是对一个1e9+7这样大的数取模,则更是emmmm,反正博主太菜了,没想过怎么处理。这时候快速幂就派上用场了。再结合几个数学公式即可解决。

二:代码及解释:

这是我从别人博客复制过来的,因为懒得自己敲了。。

比如计算 3^11,因为11的二进制可表示为1011,则根据数学推理可知:

3^11=3^(2^3+2^1+2^0)=3^(2^3)*3^(2^1)*3^(2^0)

int powadvance(int a,int b){//a是3 b是11
    int ans=1,base=a;//ans是放答案的,base是2的n次方
    while(b!=0){//即b化为二进制后,没有被读取完时执行
        if(b&1!=0)//对化为二进制的b的最后一位检测,看他是不是0,是1的时候执行步骤
          ans*=base;//即按第三个等式从右到左的顺序依次出现从右到左的三个项
        base*=base;//对2的n次方进行更新
        b>>=1;//去掉化为二进制的b的最后一位二进制数,来更新b,即原先为1011,下一轮循环的时候为101
  }
    return ans;
}

最好拿纸笔手算模拟一遍,比较好理解。

快速幂的算法就是如上所示了,再对他进行和取模操作合并

三:快速幂取模

1.数学背景:

 

运算规则

模运算与基本四则运算有些相似,但是除法例外。其规则如下:

  1. (a + b) % p = (a % p + b % p) % p (1)

  2. (a - b) % p = (a % p - b % p) % p (2)

  3. (a * b) % p = (a % p * b % p) % p (3)

  4.  a ^ b % p = ((a % p)^b) % p (4)

  5. 结合律:

  • ((a+b) % p + c) % p = (a + (b+c) % p) % p (5)

    ((a*b) % p * c)% p = (a * (b*c) % p) % p (6)

  • 交换律:

    (a + b) % p = (b+a) % p (7)

    (a * b) % p = (b * a) % p (8)

  • 分配律:

    (a+b) % p = ( a % p + b % p ) % p (9)

    ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (10)

以上是百度百科复制来的,四条基本规则比较重要一些。由基本规则可知,若想对幂取模,可对快速幂做以下的修改。

long long quick(long long a,int b,long long c) //a是3,b是11,c是1e9+7 
{  
    long long ans=1;
    while(b!=0)  
    {  
        if(b&1!=0){
        	ans=(ans*a)%c;//不一样的地方,由基本规则3可得,手动模拟一波即可
		} 
        b>>=1;
        a=(a*a)%c;//由基本规则3可得
 
    }
    return ans;
} 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值