zoukankan      html  css  js  c++  java
  • 快速幂(幂运算取模的logn算法)

    以下以求a的b次方来介绍
     
        把b转换成二进制数
     
        该二进制数第i位的权为
                          
        例如
                      
        11的二进制是1011
                  11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
        因此,我们将a¹¹转化为算
                       
        
        对于            令A[0]=a^(2^0)*1  A[1]=a^(2^1)*1   A[2]=a^(2^2)*0  A[3]=a^(2^3)*1
        
        可以看出A[N]的前半部分是A[N-1]前半部分的平方倍  则可以一直循环推(a^(2^k))^2,从右到左依次取b二进制数的位数  如果是0则不乘入答案 如果是1则乘入答案(无论乘入不乘入 一直将a的平方推下去(就前边辣个))

         直到b为0跳出循环

        
        必备的知识
     
        对于取模运算:(a*b)%c=(a%c)*(b%c)%c 成立
        //实际上
          (a +  b) % p = (a%p +  b%p) %p      

          (a  -  b) % p = (a%p  -  b%p) %p  也成立

          但是除法不成立 可以举例证明

        位运算  <<k  左移二进制数 相当于乘上2^k 

             >>k  右移二进制数  相当于除2^k

        &且 1&1=1        | 或    1|1=1 

          1&0=0            1|0=1 

          0&1=0            0|1=1 

          0&0=0            0|0=0 

          

          

     1 //实现代码
     2 //mod  c
     3 
     4 int quick(int a,int b,int c)  
     5 {  
     6     int ans=1;   //记录结果  
     7     a=a%c;   //预处理,使得a处于c的数据范围之下  
     8     while(b!=0)  
     9     {  
    10         if(b&1) ans=(ans*a)%c;   //如果b的二进制位不是0,那么我们的结果是要参与运算的  
    11         b>>=1;    //二进制的移位操作,相当于每次除以2,用二进制看,就是我们不断的遍历b的二进制位  
    12         a=(a*a)%c;   //不断的加倍  
    13     }  
    14     return ans;  
    15 }  

            

        

     
  • 相关阅读:
    使用 requests 维持会话
    使用 requests 发送 POST 请求
    使用 requests 发送 GET 请求
    requests 安装
    使用 urllib 分析 Robots 协议
    使用 urllib 解析 URL 链接
    使用 urllib 处理 HTTP 异常
    使用 urllib 处理 Cookies 信息
    使用 urllib 设置代理服务
    按单生产程序发布
  • 原文地址:https://www.cnblogs.com/reminito/p/8399797.html
Copyright © 2011-2022 走看看