zoukankan      html  css  js  c++  java
  • 快速(杨)幂方法总结

    所谓快速幂,就是快速的进行幂运算

    以下以求a的b次方来介绍[1] 
    把b转换成二进制数。
    该二进制数第i位的权为
    例如
    11的二进制是1011
    11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
    因此,我们将a¹¹转化为算

    比如2002122700^2002102300这种数就不是特别好算,会崩

    所以我们的前辈们就发明了快速幂这种东西

    而快速幂的实现有两种方式

    方法1:运用递归加位运算(更简洁)

    (任何数的0次方为1)

    int pow(int n, int m) 
    {
        if(m == 0) return 1;
        int t = pow(n, m / 2);
        t = 1LL * t * t % MD;
        if(m&1) t = 1LL * t * n % MD;    //在奇数的时候乘n
        return t;
    

     方法2:用for(正向的退回去)

    r(1);==   r=1;这是一条赋值语句

    int pow2(int n, int m)
    {
        int r(1), s(n);
        for(; m; m>>=1, s = 1LL*s*s%MD) 
            if(m&1) r = 1LL*r*s%MD;//这样做可以保证数不出错
        return r;
    }

    补充一下位运算的知识

    m&1;------>m%2;

    m>>=1;------>m/=2;

    m<<=1;------->m*=2;

    当然我的理解也不是多么准确,但我找到了一篇很好的博文,供我自己大家参考

    快速幂

    以一道题为例,讲解快速幂算法。

     

    题目:计算a^b mod c

     

    朴素算法:直接计算求值。

    var a,b,c,i,ans:longint;

    begin

      readln(a,b,c);

      ans:=1;

      for i:=1 to b do

        ans:=ans*a;

      ans:=ans mod c;

      writeln(ans);

    end.

     

    以上算法有一个缺点:当a,b很大时,容易超出longint范围。

     

     

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

     //(a*b)%c=(a%c)*(b%c)%c

    得出改进型算法:在计算过程中不断进行mod运算

     

    var a,b,c,i,ans:longint;

    begin

      readln(a,b,c);

      a:=a mod c;

      ans:=1;

      for i:=1 to b do

        ans:=(ans*a) mod c;

      ans:=ans mod c;

      writeln(ans);

    end.

    时间复杂度:O(n)

     

    这种算法也有一定缺陷:当b很大时,容易超时。

     

     

    因为a^b mod c=(a^2)^(b/2) mod c   (b为偶数);

    a^b mod c=((a^2)^(b div 2) *a) mod c  (b为奇数)。

     

       所以可以在计算过程中不断地将底数平方、指数除以2,用另一个变量记录最终答案。

    得到快速幂算法:

     

    var a,b,c,ans:int64;

    begin

    readln(a,b,c);

    write(a,'^',b,' mod ',c,'=');

    a:=a mod c;

    ans:=1;

    while b>0 do

        begin

        if b mod 2=1 then ans:=ans*a mod c;

        b:=b div 2;

        a:=(a*a) mod c;

    end;

    writeln(ans);

    end.

     

    时间复杂度:O(log2n),能在竞赛通过

    好了,我能给大家整理的就是这些了,提前祝大家六一儿童节快乐(什么鬼),毕竟大家都还是宝宝嘛!~(~ ̄▽ ̄)~

                               

    我博客里有大量的从别的博客复制过来的代码,分析,以及理解,但我一律会在文章后面标记原博客大佬博客名,其中部分会加以连接。 绝无抄袭的意思,只是为了我在复习的时候找博客方便。 如有原作者对此有不满,请在博客留言,我一定会删除该博文。
  • 相关阅读:
    html常用标签_new
    Nginx缓存
    购物车
    css的属性选择
    前端基础之css
    htm基础知识
    TypeScript(1)为什么需要TypeScript
    Electron
    Ant Design
    Umi
  • 原文地址:https://www.cnblogs.com/ZDHYXZ/p/6905171.html
Copyright © 2011-2022 走看看