二分快速幂

 计算n^k  , 当k太大时 。 不能再限制的时间内解决。  这时我们就要用二分快速幂 ,

     例如, k=8  ,   化为二进制数  1000 ;

     又可以发现,  (1)n(1)* n(1) =n(10) ,

(2) n(10)* n(10) =n(100)

(3), n(100)* n(100) =n(1000)  ;

(4) n(0)*n(0)=n(1)  例外 .

 括号里面是二进制的数,每次本身乘以本身,结果为本身的二进制数加一个0, 所以n^k , 其实只用运算3次 , 

 当K是奇数是,例如 , k=11  ,   化为二进制数  1011 ;

       n(1011)= n(1000) * n(10) *n(1)  ;  因为也是四位二进制数表示,所以也只用算3次,形如k=8时:  不同的是,  n(1011) = n(1000) * n(10) *n(1) =  (3)*(1)*(4) ; 可以看出,我们最多要算3次,也只是为了算出第(3)部,而(1)和(4) 都是之前就出来的,我们只需把他们保存起来,最后一起相乘即可, 这里就用到了 k&1 (取二进制数里面的最右边的数)  , 意思是当遇到k 二进制数里面的1时,就执行 ans *= n ; , 保存起来。   如刚刚说的,刚开始先运算第(4)部,此时遇到1,即保存,再运算第(1)部,也遇到1,又保存起来。 接着运算第(2)部时,没遇见1,不保存,最后运算第(3)部,遇见了1,又保存,   。  最后一共保存了3次,因为k二进制数1011里遇到了3次1,分别保存了第(4)(1)(3)的结果, 所以结果 ans = (4)*(1)*(3)  .

 

附代码 :

long long pow(intn , int k)

{
         longlong ans = 1;
         while(k)
         {
                   if(k&1 )                   //遇见1,即保存 :
                      ans *= n ;
                   n*= n ;    
                   k>>=1;            // 向右移一位。本来是1011,执行后,变101。
         }
           returnans ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值