zoukankan      html  css  js  c++  java
  • 快速幂取模算法

    快速幂顾名思义,就是快速算某个数的多少次幂。其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高。——bybaidu

    原理:

    以求a的b次方来介绍

    把b转换成二进制数。

    该二进制数第i位的权为

    例如:

    11的二进制是  1011

    11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1

    因此,我们将a¹¹转化为算

    实现:

    快速幂可以用位运算这个强大的工具实现。

    代码比较:

    常规求幂

    intpow1(int a,int b)
    {
        int r=1;
        while(b--)
            r*=a;
        return r;
    }

    二分求幂(一般)

    intpow2(int a,int b)
    {
        int r=1,base=a;
        while(b!=0)
        {
            if(b%2)
                r*=base;
            base*=base;
            b/=2;
        }
        return r;
    }

    快速求幂(位操作)

    intpow3(int a,int b)
    {
        int r=1,base=a;
        while(b!=0)
        {
            if(b&1)
                r*=base;
            base*=base;
            b>>=1;
        }
        return r;
    }


    其中二分求幂与快速求幂都是利用了二进制数的思想。

    蒙哥马利快速幂取模算法,简单漂亮

    int pow3(int a,int b,int c)
    {
        int ans=1;
        a=a%c;
        while(b!=0)
        {
            if(b&1)
                ans=(ans*a)%c;
            a=(a*a)%c;
            b>>=1;
        }
        return ans;
    }

     算法详解:

    公式:(a*b)mod c=[(a mod c)*(b mod c)]mod c;

    证明:

    a mod c=d => a=t*c+d;

    b mod c=e => b=k*c+e;

    a*b mod c= (t*c+d)*(k*c+e)mod c

    =(t*k*c*c+(t*e+d*k)*c+d*e)mod c

    =d*e mod c=[(a mod c)*(b mod c)]mod c;

    上面公式为下面公式的引理,即积的取余等于取余积的取余。

    公式:a^b mod c =(a mod c)^b mod c;

    证明:[(a mod c)^b]mod c

    =[((a mod c) mod c)^b]mod c(由上面公式的迭代)

     [(a mod c)^b]modc=a^b mod c;

    证明了以上公式以后,我们可以先让a关于c取余,这样可以大大减小a的大小。

  • 相关阅读:
    奶酪工厂
    P1080 国王游戏(非高精版)
    【洛谷P2150】[NOI2015] 寿司晚宴
    【洛谷P3349】[ZJOI2016]小星星
    【洛谷P5785】[SDOI2012]任务安排
    【模板】严格次短路
    【洛谷P3647】[APIO2014]连珠线
    2021.10.27NOIP模拟总结
    【树形DP】CF1016F Road Projects
    2021CSP-S 总结
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/4123015.html
Copyright © 2011-2022 走看看