快速幂、取余运算、快速幂取余、欧拉降幂

20 篇文章 0 订阅
13 篇文章 0 订阅

快速幂

对于a的n次方,如果我们老老实实用a每次的结果乘以自身的话,那需要乘n次,在n很大的时候速度很慢,但是,如果我们将n用二进制表示,这样就可以将乘法次数降到log(n)次。

def pickPow(a,b):
    s=1
    while b>0:
        if b&1:s*=a
        a*=a
        b>>=1
    return s

mod(%)取余运算性质

在这里插入图片描述

快速幂求余

其实就是快速幂与求余性质的结合,由公式2推导出来(有人评论区问再追加证明过程),这里直接上代码,简单易懂。

def qickPowMod(a,b,p):
    res=1
    a=a%p
    while b>0:
        if b&1:res=(res*a)%p
        a=(a*a)%p
        b>>=1
    return res

随着b的增大快速幂的运行速度的优势是很明显的

-----------当b为60-----------
快速幂取余结果 1
常规求余结果 1
快速求余耗时: 0.0 常规求余耗时 0.0
-----------当b为674-----------
快速幂取余结果 4
常规求余结果 4
快速求余耗时: 0.0 常规求余耗时 0.0
-----------当b为6759-----------
快速幂取余结果 1
常规求余结果 1
快速求余耗时: 0.0 常规求余耗时 0.0
-----------当b为67630-----------
快速幂取余结果 2
常规求余结果 2
快速求余耗时: 0.0 常规求余耗时 0.02298712730407715
-----------当b为676357-----------
快速幂取余结果 2
常规求余结果 2
快速求余耗时: 0.0 常规求余耗时 0.48773908615112305
-----------当b为6763614-----------
快速幂取余结果 1
常规求余结果 1
快速求余耗时: 0.0 常规求余耗时 18.909112215042114

欧拉函数

欧拉函数就是对1-n上n的质数的个数的统计。

def oula(n):
    s=n
    i=2
    while i*i<=n:
        if n%i==0:
            s=s//i*(i-1)
            while n%i==0:
                n=n//i
        i+=1
    if n>1:s=s//n*(n-1)
    return s

欧拉降幂

再一般情况下,我们认为,用快速幂求余就已经够用了,但是,随着b的不断增大,快速幂也不那么好使了,特别是当b的大小远大于p的这时候,那有什么方法解决吗?这时候欧拉降幂就上场了。(欧拉真伟大!)
手撕欧拉降幂公式。
在这里插入图片描述

上代码

def oula(n):
    s=n
    i=2
    while i*i<=n:
        if n%i==0:
            s=s//i*(i-1)
            while n%i==0:
                n=n//i
        i+=1
    if n>1:s=s//n*(n-1)
    return s
def qickPowMod(a,b,p):
    res=1
    a=a%p
    while b>0:
        if b&1:res=(res*a)%p
        a=(a*a)%p
        b>>=1
    return res
a,b,p=1000,20000000,100007
phi=oula(p)
if b<phi:
    print(qickPowMod(a,b,p))
elif b==phi:
    print(qickPowMod(a,b%phi,p))
else:
    print(qickPowMod(a, b % phi+phi, p))

在快速幂求余算法与正常求余算法的对比中,当b达到6000000左右,普通的求余算法就基本上完全败下阵来,但是通过下面的例子我们可以发现,欧拉公式在b的数目惊人的巨大时,欧拉降幂还是略占上风,但是两公式在处理这么大数时的能力,还是让人惊叹。

-----------当b为92-----------
快速幂取余结果 99722
常规求余结果 99722
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为945-----------
快速幂取余结果 44531
常规求余结果 44531
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9465-----------
快速幂取余结果 94567
常规求余结果 94567
快速求余耗时: 0.0009984970092773438 欧拉求余耗时 0.0
-----------当b为94673-----------
快速幂取余结果 66143
常规求余结果 66143
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946744-----------
快速幂取余结果 67063
常规求余结果 67063
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467-----------
快速幂取余结果 35213
常规求余结果 35213
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674673-----------
快速幂取余结果 2816
常规求余结果 2816
快速求余耗时: 0.0010008811950683594 欧拉求余耗时 0.0
-----------当b为946746784-----------
快速幂取余结果 62917
常规求余结果 62917
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467899-----------
快速幂取余结果 3368
常规求余结果 3368
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679053-----------
快速幂取余结果 71992
常规求余结果 71992
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790617-----------
快速幂取余结果 35882
常规求余结果 35882
快速求余耗时: 0.0009965896606445312 欧拉求余耗时 0.0
-----------当b为9467467906195-----------
快速幂取余结果 70323
常规求余结果 70323
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062013-----------
快速幂取余结果 72490
常规求余结果 72490
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620147-----------
快速幂取余结果 4489
常规求余结果 4489
快速求余耗时: 0.0009996891021728516 欧拉求余耗时 0.0
-----------当b为9467467906201479-----------
快速幂取余结果 20770
常规求余结果 20770
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014806-----------
快速幂取余结果 4117
常规求余结果 4117
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148136-----------
快速幂取余结果 17231
常规求余结果 17231
快速求余耗时: 0.0009989738464355469 欧拉求余耗时 0.0
-----------当b为9467467906201481441-----------
快速幂取余结果 59935
常规求余结果 59935
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814477-----------
快速幂取余结果 25432
常规求余结果 25432
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144853-----------
快速幂取余结果 25075
常规求余结果 25075
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448612-----------
快速幂取余结果 32323
常规求余结果 32323
快速求余耗时: 0.0010006427764892578 欧拉求余耗时 0.0
-----------当b为94674679062014814486147-----------
快速幂取余结果 95572
常规求余结果 95572
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861569-----------
快速幂取余结果 44531
常规求余结果 44531
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615727-----------
快速幂取余结果 25652
常规求余结果 25652
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814486157273-----------
快速幂取余结果 60137
常规求余结果 60137
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572807-----------
快速幂取余结果 66748
常规求余结果 66748
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728091-----------
快速幂取余结果 54099
常规求余结果 54099
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814486157280994-----------
快速幂取余结果 18203
常规求余结果 18203
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809945-----------
快速幂取余结果 67232
常规求余结果 67232
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728099532-----------
快速幂取余结果 93001
常规求余结果 93001
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814486157280995354-----------
快速幂取余结果 89895
常规求余结果 89895
快速求余耗时: 0.0009992122650146484 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809953541-----------
快速幂取余结果 92587
常规求余结果 92587
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728099535444-----------
快速幂取余结果 15833
常规求余结果 15833
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814486157280995354479-----------
快速幂取余结果 87191
常规求余结果 87191
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809953544834-----------
快速幂取余结果 63932
常规求余结果 63932
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728099535448387-----------
快速幂取余结果 67025
常规求余结果 67025
快速求余耗时: 0.0010018348693847656 欧拉求余耗时 0.0
-----------当b为94674679062014814486157280995354483921-----------
快速幂取余结果 11449
常规求余结果 11449
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809953544839233-----------
快速幂取余结果 19117
常规求余结果 19117
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728099535448392356-----------
快速幂取余结果 2322
常规求余结果 2322
快速求余耗时: 0.0 欧拉求余耗时 0.0010187625885009766
-----------当b为94674679062014814486157280995354483923638-----------
快速幂取余结果 94579
常规求余结果 94579
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809953544839236430-----------
快速幂取余结果 64850
常规求余结果 64850
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728099535448392364357-----------
快速幂取余结果 20630
常规求余结果 20630
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814486157280995354483923643609-----------
快速幂取余结果 37633
常规求余结果 37633
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809953544839236436117-----------
快速幂取余结果 38478
常规求余结果 38478
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728099535448392364361203-----------
快速幂取余结果 58295
常规求余结果 58295
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814486157280995354483923643612065-----------
快速幂取余结果 66453
常规求余结果 66453
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809953544839236436120720-----------
快速幂取余结果 69416
常规求余结果 69416
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728099535448392364361207229-----------
快速幂取余结果 21940
常规求余结果 21940
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814486157280995354483923643612072318-----------
快速幂取余结果 73483
常规求余结果 73483
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809953544839236436120723233-----------
快速幂取余结果 36674
常规求余结果 36674
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为9467467906201481448615728099535448392364361207232425-----------
快速幂取余结果 55592
常规求余结果 55592
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为94674679062014814486157280995354483923643612072324321-----------
快速幂取余结果 9412
常规求余结果 9412
快速求余耗时: 0.0 欧拉求余耗时 0.0
-----------当b为946746790620148144861572809953544839236436120723243266-----------
快速幂取余结果 41483
常规求余结果 41483
快速求余耗时: 0.0009987354278564453 欧拉求余耗时 0.0
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值