问题
给定正整数b,e,m,求:
c=be(modm) 简单算法
按照次方运算的原理,初始化c=1,重复e次:
c=(c×b)modm 即为所求,该算法的时间复杂度为O(e)。
二进制算法
根据二进制可知,任何正整数e都可以用n个2的次方和来表示:
e=i=0∑n−1ai⋅2i 其中n是正整数e中1的数量,ai要么为0要么为1,且an−1=1。因此be可以转换为:
be=b(∑i=0n−1ai⋅2i)=i=0∏n−1(b2i)ai 因此模幂运算转换为:
c≡i=0∏n−1(b2i)ai(modm) 计算每个元素(b2i)ai,若ai=0则结果必然为1,不必计算,若ai=1则需要2i次乘法,即时间复杂度为O(2i)(其中0≤i≤n−1)。
该算法的时间复杂度为O(∑i=0n−12i⋅ai)。
求正整数e中所有为1的bit位的方法,与本书第三章DataStructure中FenwickTree一节使用的方法一样,不再赘述。
快速求幂算法
快速求幂算法基于以下公式:
be={1e=0be=1(b×(b2)2e−1)modmbisodd((b2)2e)modmbiseven 该算法的时间复杂度为O(log2e)。
源码
ModularExponentiation.h
ModularExponentiation.cpp
测试
ModularExponentiationTest.cpp