zoukankan      html  css  js  c++  java
  • 快速幂取模&快速乘取模

    快速幂取模

    即快速求出(a^b)mod c 的值。由于当a、b的值非常大时直接求a^b可能造成溢出,并且效率低。

    思路

    原理就是基于(a*b \% c = ((a \% c)*(b \% c))\% c),(a^b \% c = (a \% c)^b \% c)公式。

    求解快速幂:

    设指数b用二进制表示为(b = (b_n b_{n-1}...b_2b_1b_0)_2)

    (b = b_0 + b_1*2^1 + b_2*2^2+...+b_{n-1}*2^{n-1} + b_n*2^n)

    (a^b = a^{b_0 + b_1*2^1 + b_2*2^2+...+b_{n-1}*2^{n-1} + b_n*2^n} = a^{b0}*a^{b_1*2^1}*a^{b_2*2^2} *...*a^{b_{n-1}*2^{n-1}} * a^{b_n*2^n})

    (a^b \% c = a^{b0}*a^{b_1*2^1}*a^{b_2*2^2} *...*a^{b_{n-1}*2^{n-1}} * a^{b_n*2^n} \% c)

    (K_n = (a^{b_n*2^n})\%c),求Kn的话,当bn=0时Kn=1,bn=1时(Kn=(a^{2^n})\%c),因此再考虑计算((a^{2^n})\%c)

    ((a^{2^n})\%c = [(a^{2^{n-1}}\%c)*(a^{2^{n-1}}\%c)]\%c)由此递推。

    代码

    python

    def quick_powmod(a, b, c):
        a = a % c
        ans = 1 # 存放结果
        while b != 0:
            if b & 1: # 二进制与
                ans = (ans * a) % c
            a = (a * a) % c # 取模是防止溢出
            b >>= 1 # 二进制向右移动一位
        return ans
    

    例如a=2 b=10 c=3,b的二进制表示为1010。

    (2^{10} = 2^{0+ 1*2^1+0*2^2+1*2^3}),b的二进制位从右往左取,为0时,累乘a,为1时,将累乘结果乘到ans里。

    快速乘取模

    使用二进制将乘法转换为加法。

    思路

    与快速幂取模类似,将一个乘数转换为二进制计算。

    例如(20*14 = 20*(1110)_2 = 20*2^0*0 + 20*2^1*1+20*2^2*1+20*2^3*1)

    代码

    Python

    def quick_mulmod(a, b, c):
        ans = 0
        a = a % c
        while b != 0:
            if b & 1 :
                ans = (ans + a) % c
            a = (2*a) % c
            b >>= 1
        return ans
    

    乍一看还是很不好懂的,举个例子推导一遍就明白了。

  • 相关阅读:
    Iaas/paas/saas 三种模式分别都是做什么?
    sender e
    xshell
    JDK 和JRE区别
    mongodb高级聚合查询
    MongoDB 官方文档中的 aggregate 例子当中的 $sum: 1 , 这里的 1 起什么作用?
    MySQL 当记录不存在时插入,当记录存在时更新
    html中跳转方法(含设定时间)
    处理分页
    Js弹出层,弹出框代码
  • 原文地址:https://www.cnblogs.com/KRDecad3/p/11603873.html
Copyright © 2011-2022 走看看