快速幂取模

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

思想:

解释一下a^b mod c:

a^b mod c=a^(f[0]*2^0+f[1]*2^1+f[2]*2^2...f[t]*2^t)

因为a*b mod c= ((a mod c) *b) mod c

所以

a^b mod c=(((f[0]*2^0 mod c)*f[1]*2^1 mod c)......*f[t]*2^t mod c)

用这种方法解决a^b mod c 时间复杂度

2^t<=b<2^(t+1)

t<=log(2)b<t+1

因为b是个整数所以

t=log(2)b

时间复杂度比直接循环求a^b大大的降低了

模取幂运算

事实上,m^e mod n可以直接计算,没有必要先算m^e。

m^e mod n叫做模取幂运算,根据简单的数论知识,很容易设计一个分治算法。具体如下:

设<b[k], b[k-1],...,b[1],b[0]>是整数b的二进制表示(即b的二进制有k+1位,b[k]是最

高位),下列过程随着c的值从0到b成倍增加,最终计算出a^c mod n

Modular-Exponentiation(a, b, n)

1. c ←0

2. d ←1

3. 设<b[k],b[k-1],..b[0]>是b的二进制表示

4. for i←k downto 0

5. do c ←2c

6. d ←(d*d) mod n

7. if b[i] = 1

8. then c ←c + 1

9. d ←(d*a) mod n

10. return d

首先说明一下,上述伪代码中用缩紧表示语句之间的层次关系,例如第5~9行都是for循环体

内的语句,第8~9行都是then里面的语句。这是我比较喜欢的一种表示方法;)

上述伪代码依次计算出的每个幂或者是前一个幂的两倍,或者比前一个幂大1。过程依次从右到左逐个读入b的二进制表示已控制执行哪一种操作。循环中的每次迭代都用到了下面的

两个恒等式中的一个:

a^(2c) mod n = (a^c mod n)^2

a^(2c+1) mod n = a * (a^c mod n)^2

用哪一个恒等式取决于b[i]=0还是1。由于平方在每次迭代中起着关键作用,所以这种方法叫做“反复平方法(repeated squaring)”。在读入b[i]位并进行相应处理后,c的值与b的

二进制表示<b[k],b[k-1],..b[0]>的前缀的值相同。事实上,算法中并不真正需要变量c,只是为了说明算法才设置了变量c:当c成倍增加时,算法保持条件d = a^c mod n 不变,直

至c=b。

如果输入a,b,n是k位的数,则算法总共需要执行的算术运算次数为O(k),总共需要执行的位操作次数为O(k^3)。

相关文档
最新文档