zoukankan      html  css  js  c++  java
  • 学习记录:快速幂

    学习记录 快速幂

    快速幂的递归实现

    假设要算(7^9),如果采取普通计算,也就是(7*7*7*7*7*7*7*7*7),共需要8次运算。

    运用二分的思想,先算(7^4),然后通过(7^4*7^4*7)来计算$7^9 $,这样就只需要(3+1+1=6)次计算,然而这样还不够彻底,(7^4)还可以通过分解成(7^2*7^2)的形式,这样递归下去,就得到了时间复杂度为(O(logn))的快速幂算法。

    int Quickpow(int a,int n)
    {
    	if (n==0)
    		return 1;
    	else if (n%2==1)
    		return Quickpow(a,n-1)*a;
    	else{
    		int temp=Quickpow(a,n/2);//必须先保存下来,否则会算两遍
    		return temp*temp;
    	}
    }
    

    做题的时候,幂的结果可能会非常大,需要对一个大数取余,这时将上面的函数改成long long,在运算的每一步都要取余结果也要取余啊!改进代码如下:

    const int MOD=1e9+7;
    typedef long long ll;
    ll Quickpow(ll a,ll n)
    {
    	if (n==0)
    		return 1;
    	else if (n%2==1)
    		return Quickpow(a,n-1)*a%MOD;
    	else{
    		ll temp=Quickpow(a,n/2)%MOD;
    		return temp*temp%MOD;
    	}
    }//可以过洛谷P1226,就是结果也必须取余
    

    非递归实现

    非递归实现主要用了二进制的思想。

    在上面的递归实现中不难发现是每次都是将结果分割为两半,这正好对应了二进制。而且众所周知,位运算是比乘法运算快的,运用非递归实现因此比递归实现快一点。

    还是(7^9)的例子,(9)的二进制形式为(1001),意味着(7^{(1001)_2})可以拆分为(7^{(1000)_2}*7^{(1)_2}),以此类推,任何幂总可以拆分成(a^{2^b})相乘的形式,因此就有了思路。

    1. 总体思路就是从二进制最后一位开始算起,如果在这一位的二进制数为1,则说明需要加上这一块;若是0则跳过。然后到下一位。不过在此用位运算的右移实现。
    2. 计算(a^{2^b}),可以用底数自乘来实现,在每次运算中代表在这一位的(7^{2^{x}})是多少。
    3. 判断二进制的情况,需要用一些位运算的基本知识。

    非递归计算(7^9)的过程:

    临时变量 指数情况(二进制) 目前的运算结果
    7((7^{2^0 })) 1001 1*7=7
    49((7^{2^1})) 0100 7
    2401((7^{2^2})) 0010 7
    5764801((7^{2^3})) 0001 7*5764801=40353607

    代码实现:

    int Quickpow(int a,int n)
    {
    	int res=1;
    	while (n){			//最终右移的结果为0
    		if (n&1)		//指数二进制末尾为1
    			res*=a;		//乘以当前的底数
    		a*=a;			//底数自乘
    		n>>=1;			//指数右移一位
    	}
    	return res;
    }
    
  • 相关阅读:
    _ 下划线 Underscores __init__
    Page not found (404) 不被Django的exception中间件捕捉 中间件
    从装修儿童房时的门锁说起
    欧拉定理 费马小定理的推广
    线性运算 非线性运算
    Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
    Avoiding Full Table Scans
    批量的单向的ssh 认证
    批量的单向的ssh 认证
    Corrupted MAC on input at /usr/local/perl/lib/site_perl/5.22.1/x86_64-linux/Net/SSH/Perl/Packet.pm l
  • 原文地址:https://www.cnblogs.com/Salty-Fish/p/12863502.html
Copyright © 2011-2022 走看看