zoukankan      html  css  js  c++  java
  • acm数论之旅(转载) -- 快速幂

     0和1都不是素数,也不是合数。

    a的b次方怎么求

    pow(a, b)是数学头文件math.h里面有的函数

    可是它返回值是double类型,数据有精度误差

    那就自己写for循环咯

    复制代码
    LL pow(LL a, LL b){//a的b次方
        LL ret = 1;
        for(LL i = 1; i <= b; i ++){
            ret *= a;
        }
        return ret;
    }
    复制代码

    完美

    可是题目是b的范围是1 <= b <= 1e9(#°Д°)

    超时,妥妥的。。。

    看个例子

    比如计算

    2*2*2*2*2*2*2*2*2*2*2

    可以这样算

    原式=4*4*4*4*4*2

    =8*8*4*2

    =16*4*2

    你看,相同的可以先合并,减少计算步骤

    如果题目说数据很大,还需要求余,那么代码就可以这么写

    复制代码
    1 LL pow_mod(LL a, LL b, ll MOD){//a的b次方
    2     if(b == 0) return 1;
    3     LL ret = pow_mod(a * a % MOD, b/2, Mod);
    5     if(b & 1) ret = ret * a % MOD;
    6     return ret;
    7 }
    复制代码

    这是递归写法

    然后还有递推写法

    复制代码
     1 LL pow_mod(LL a, LL b){//a的b次方
     2     LL ret = 1;
     3     while(b != 0){
     4         if(b % 2 == 1){
     5             ret = (ret * a) % MOD ;
     6         }
     7         a = (a * a ) % MOD ;
     8         b /= 2;
     9     }
    10     return ret;
    11 }
    复制代码

    对于位运算熟的小盆友,还可以写成位运算形式,速度又快,又好理解,在加一个求余p,代码如下

    复制代码
    1 LL pow_mod(LL a, LL b, LL p){//a的b次方求余p 
    2     LL ret = 1;
    3     while(b){
    4         if(b & 1) ret = (ret * a) % p;
    5         a = (a * a) % p;
    6         b >>= 1;
    7     }
    8     return ret;
    9 }
    复制代码

    有了快速幂,于是,快速乘诞生了

    复制代码
    1 LL mul(LL a, LL b, LL p){//快速乘,计算a*b%p 
    2     LL ret = 0;
    3     while(b){
    4         if(b & 1) ret = (ret + a) % p;
    5         a = (a + a) % p;
    6         b >>= 1;
    7     }
    8     return ret;
    9 }
    复制代码

     https://vjudge.net/contest/240113#problem/J

    解释

    https://blog.csdn.net/rain722/article/details/64442335

    https://blog.csdn.net/wanghandou/article/details/69666620

    题意:
             输入n^k,输出n^k的前3位与后3位.

    思路:
    最后的三位可以直接快速幂取余,但要注意不够要补前导0.

    求前三位则需要一些数学知识对于给定的一个数n,它可以写成10^a,其中这个a为浮点数,则n^k=(10^a)^k=10^a*k=(10^x)*(10^y);

    其中x,y分别是a*k的整数部分和小数部分对于t=n^k这个数,它的位数由(10^x)决定,它的位数上的值则有(10^y)决定,因此我们

    要求t的前三位,只需要将10^y求出,再乘以100,就得到了它的前三位。

    fmod(x,1)可以求出x的小数部分

                                                                                       
               

  • 相关阅读:
    windows10(64位)Anaconda3+Python3.6搭建Tensorflow(cpu版本)及keras
    Windows10下安装pytorch并导入pycharm
    应用程序无法正常启动0xc000007b解决
    Clion安装配置
    Android Studio安装&&安装bug
    VMWARE虚拟机安装64位系统此主机支持IntelVTx 但IntelVTx处于禁用状态
    A. Text Volume
    1001 数组中和等于K的数对
    11100
    Seek the Name, Seek the Fame
  • 原文地址:https://www.cnblogs.com/downrainsun/p/9755074.html
Copyright © 2011-2022 走看看