zoukankan      html  css  js  c++  java
  • [数论]快速幂取模

    问题描述:

    已知底数a,指数b,取模值p,求 ab % p 的值


    朴素算法

    设初始值为1,循环b次,每次乘上a后再取模一下

    时间复杂度为O(n),虽然看着不高,但是一旦指数给得过大,肯定会TLE

    这里代码就不给出来了,就是一个简单的循环


    快速幂

    先不讨论取模,根据幂运算可知

    当b为偶数时:ab=a(b/2)*2=(a2)b/2

    当b为奇数时:ab=a*ab-1=a*(a2)(b-1)/2

    比如:28=44=162=256  直观一点:2*2*2*2*2*2*2*2=4*4*4*4=16*16=256

    比如:29=44*2=162*2=256*2=512  直观一点:2*2*2*2*2*2*2*2*2=4*4*4*4*2=16*16*2=256*2=512

    也就是每次将指数除以2,底数变为原来的平方,如果指数为奇数,则单独取一个出来另乘

    时间复杂度为O(logn)

     1 int pow_mod(int a,int b){
     2     int ans=1,base=a;
     3     while(b){
     4         if(b&1)//等价于判断奇偶
     5             ans*=base;
     6         base*=base;
     7         b>>=1;//将指数除以2
     8     }
     9     return ans;
    10 }

    快速幂取模

    由于幂的算术递增地非常快,long long也很容易超,这时候就需要取模一下,一般都是模以一个质数

    这时候我们需要了解数论中模运算的分配律:

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

    根据上述定理,我们还可以得到:

    ab % p = (a % p)b % p

    也就是指,在乘法中,模的顺序并不影响最后的结果

    然后我们就可以在做快速幂的过程中加上模运算

     1 int pow_mod(int a,int b,int p){
     2     int ans=1,base=a%p;
     3     while(b){
     4         if(b&1)//等价于判断奇偶
     5             ans=(ans*base)%p;
     6         base=(base*base)%p;
     7         b>>=1;//将指数除以2
     8     }
     9     return ans;
    10 }
    正因为是最弱,所以才理解智慧之强
  • 相关阅读:
    树的定义与存储
    软件测试概论二
    软件测试概论
    抽象数据类型
    java编程总结01---20190214
    java 按行读取本文文件并存放到mongodb中
    刷题感悟
    刷题感悟- Binary Tree Path Sum
    java io与nio
    java IO 学习笔记
  • 原文地址:https://www.cnblogs.com/Yanick/p/11239817.html
Copyright © 2011-2022 走看看