zoukankan      html  css  js  c++  java
  • [算法]快速幂

    (基本上是从百度百科搬过来的,虽然本大佬是宇宙无敌牛逼,但是有错还请指出~谢谢,有空请你一起抠脚~么么哒)

    求底数为a的n次幂:

    一般解法都是“a*a*a……*a”,复杂度为O(n);

    下面是快速幂解法:

    1.把n转换为二进制,例如:

      11转换为二进制1011;

    2.将n得到的二进制以“数位的值*权值”的和表示,例如:

      11可表示为“1*(2^3)+0*(2^2)+1*(2^1)+1*(2^0)”;

    3.由第2点可以得到a的11次方为:

      a^(1*(2^3))*a^(0*(2^2))*a^(1*(2^1))*a^(1*(2^0));

    那么就可得以下代码(下面的代码将结果取模了,因为一般的运算结果过于庞大,题目或者实际都是要求是将结果取模,如果不需要取模自行删除即可),时间复杂度是O(log2n)

     1 #include<iostream>
     2 using namespace std;
     3 int main()//计算a^n % mod
     4 {
     5     long long a, n, mod;
     6     long long re = 1;
     7     cin>>a>>n;
     8     while(n)
     9     {
    10         if(n & 1){//判断n的最后一位是否为1
    11             re = (re * a) % mod;
    12         }
    13         n >>= 1;//移位操作,去掉n的最后一位
    14         a = (a * a) % mod;
    15         /*这里用了一个技巧,a*a即求出了a^(2^(i-1))
    16         *不知道这是什么的看原理 
    17         *a^(2^(i-1))*a^(2^(i-1))=a^(2^i)
    18         *而且一般情况下a*b mod c =(a mod c)*(b mod c) mod c*/
    19     }
    20     cout<< re % mod;
    21     return 0;
    22 }

    需要注意的是,可能很多人都看不懂14行的含义:

    a = (a * a) % mod;

    不理解的话就只能是生搬硬套的模板,没有任何意义。虽然代码注释里都说了,但是还是得讲一下自己的理解,我也怕以后忘记了,还是以a的11次方为例:

    由于n的二进制的数位的值只会是1和0,因此上面第3点得到的式子中的1省去,有:

    a^(1*(2^3))*a^(0*(2^2))*a^(1*(2^1))*a^(1*(2^0))  =>  a^(2^3) * a^(0*(2^2)) * a^(2^1) * a^(2^0)

    看到上式2的指数,那么注释里的 “ a^(2^(i-1))*a^(2^(i-1))=a^(2^i) ” 是不是就清晰易懂了呢?

    至于递归的代码,这里就不给了,百度百科里面都有,感谢亲亲看完哟~

  • 相关阅读:
    POJ 1753(1)
    2015.12 杭电校赛 Bitwise Equations
    codeforces B
    POJ2387 水水最短路
    CodeForces 337C SDUT秋季训练--周赛(10.31)
    HDU 1241
    POJ 3126 Prime Path
    HDU 2612
    POJ 1426 Find The Multiple
    day94 flask-session 表单验证 信号 SQLALchemy
  • 原文地址:https://www.cnblogs.com/chasemeng/p/12790776.html
Copyright © 2011-2022 走看看