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
    

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

  • 相关阅读:
    Windows&Android&ios后台机制总结
    启动Mongodb服务
    js获取一个月有多少天
    NaN类型和数字相加为NaN
    sql将datetime类型与字符串进行比较
    存储过程拼接sql
    将list转换成用逗号连接的字符串
    sql在查询结果集上新增一列
    让两个div排列在一行
    返回不同数据库类型的IDBConnection
  • 原文地址:https://www.cnblogs.com/KRDecad3/p/11603873.html
Copyright © 2011-2022 走看看