快速幂求余

快速幂问题(求a^b)

我们都知道当指数为偶数的时候,对于a**b,可以变为(a ** 2) ** (b/2)。
而当指数为奇数的时候,对于a ** b,可以化简为a*(a ** (b-1)),然后即可以化简为a*((a ** 2) ** ((b-1)/2))
如此我们便可知道 如果b为奇数,则将b减一除二,将一个a取到外面,同时对里面的a平方。
如果b为偶数,则直接除二,同时对a平方。
若b为7,a为2。
则a变为4,b变为3,ans变为2*(2 ** 2) ** 3。
然后继续向后运,(注意此时a为4),a变为16,b变为1,ans变为2* 4*(2 ** 2 ** 2) ** 1。
结果为128。

若b为10,a为2。
则a变为4,b变为5,ans变(2 ** 2) ** 5。
然后继续向后运,(注意此时a为4),a变为16,b变为2,ans变为4*(2 ** 2 ** 2) ** 2。
再之后(注意此时a为16),a变为256,b变为1,ans变为4*(2 ** 2 ** 2 ** 2) ** 1。
结果为1024。

在这应注意b每次变化的时候都会对a平方(当然,也可以当b为奇数的时候使b减一,然后再判断为偶数),为不影响结果,在这我们应该在引入一个变量(ans),在对b进行加减的时候我们应导出一个a对ans进行变换,而不是直接改变a。只有当b除2时才对a进行改变,使其平方。

求a ** b%c
代码如下:

n=int(input())
for i in range(n):
    a,b,c=[int(x)for x in input().split()]
    a=a%c #由取模的运算规则可知 a**b%c=(a%c)**b%c
    ans=1
    while b!=0:
        if b%2==1:#若b为奇数
            b=b//2#b-1除2,直接取整商即可
            ans=(ans*a)%c#若为奇数则控制ans乘一个此时的a
        else:#若b为偶数
            b=b/2 #直接除2即可
        a=(a*a)%c#因与判断平行 即每次运行均会对a平方
    print(ans)#应注意因为取模运算较大 应在每次运行程序是均对结果取模

该方法根据二进制方法改编
原式如下

while b!=0:
        if b&1:
            ans=(ans*a)%c
        b>>=1        
        a=(a*a)%c

你可能感兴趣的:(快速幂求余)