• 让幂运算更效率——快速幂


      在日常解决问题的过程中,我们常常会遇到求ab类似的问题,对于这种问题,我们一般的解决方法就是最朴素的方法就能解决,它的时间复杂度为O(b)。
    1 int power(int a,int b)    //求a的b次方
    2 {
    3     int i,ans=1;
    4     for(i=0;i<b;i++)
    5         ans*=a;
    6     return ans;
    7 }

    但是对于某些题目,当b的数据变大的时候,可能就会超时,这时候我们就需要用快速幂来优化我们的程序了。

    一、快速幂
    快速幂的原理来自于十进制二进制相互转换的加权系数法,对于任意一个十进制数,我们可以把它写成2k1+2k2+2k3+…+2kn+…(k=0,1,2…),继而转化为二进制,如10=21+23=(1010)2。那么对于ab的次数b来说,也是如此。我们可以把b拆成2k1+2k2+2k3+…+2kn+…(k=0,1,2…),那么ab就变成了a(2^k1+2^k2+2^k3+…+2^kn+…)(k=0,1,2…),继而可以化成a2^k1×a2^k2×a2^k3×…×a2^k1。这样一来,我们就把原来的时间复杂度O(b)压缩到O(log2b),这是一个很可观的改进。
    怎么用代码来实现呢?这里我们需要用到两个位运算&和>>,其中&是按位与,我们在代码中用(n&1)来判断n的二进制最后一位是不是1。n>>1的作用是二进制数左移一位,效果等同于除以2,但是时间要比除以2稍快。
    综上,我们就可以得到快速幂的实现代码了。
     1 long long fastpow(long long n,long long multi)
     2 {
     3     long long ans=1,base=n;
     4     while(multi)
     5     {
     6         if(multi&1) ans=(ans*base);
     7         base=(base*base);
     8         multi>>=1;
     9     }
    10     return ans;
    11 }

    但是在实际解题中很多情况下进行不了几次幂运算就会溢出,所以常常会让我们取模,下面我们来解决这个问题。

    二、快速幂取模
    求解快速幂取模的问题并不需要对算法做太多的改动,在乘运算时加上取模即可,但要注意取模尽量要考虑全面,因为不一定什么地方就会爆掉了。
    代码如下:
     1 long long fastpow(long long n,long long multi,long long mod)
     2 {
     3     long long ans=1,base=n;
     4     while(multi)
     5     {
     6         if(multi&1) ans=(ans*base)%mod;
     7         base=(base*base)%mod;
     8         multi>>=1;
     9     }
    10     return ans%mod;
    11 }

    三、矩阵快速幂

    (施工中orz)

    四、相关题目
    1.快速幂例题  Luogu P1226
    代码:
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 long long mod,n,multi;
     6 
     7 long long fastmulti(long long n,long long multi,long long mod)
     8 {
     9     long long ans=1,base=n;
    10     while(multi)
    11     {
    12         if(multi&1) ans=(ans*base)%mod;
    13         base=(base*base)%mod;
    14         multi>>=1;
    15     }
    16     return ans%mod;
    17 }
    18 
    19 int main()
    20 {
    21     scanf("%lld%lld%lld",&n,&multi,&mod);
    22     long long ans;
    23     ans=fastmulti(n,multi,mod);
    24     printf("%lld^%lld mod %lld=%lld",n,multi,mod,ans);
    25     return 0;
    26 }
    Luogu P1226

    Author : Houge  Date : 2019.6.2

    Update log : 

  • 相关阅读:
    在java中使用ffmpeg将amr格式的语音转为mp3格式
    keras实现不同形态的模型
    TF版本的Word2Vec和余弦相似度的计算
    TensorFlow中的两种conv2d方法和kernel_initializer
    CNN中的padding
    记一次sqoop同步到mysql
    理解HDFS
    TensorFlow中的优化算法
    使用TensorFlow实现分类
    使用TensorFlow实现回归预测
  • 原文地址:https://www.cnblogs.com/CSGOBESTGAMEEVER/p/10964209.html
Copyright © 2020-2023  润新知