ACM知识点——位运算下的快速幂

如果你对 pow(2,3)的理解还停留在3个2相乘,那就太low了,其实对幂运算还有一种更快,更简洁的算法——快速幂

其实快速幂的本质原理非常简单,我们已知 24求28,不就是 24 * 24嘛,快速幂就是这个原理。

那么现在你可能会问,如果是奇数次幂该怎么办?
29就可以用 2 * 28来计算嘛。

所以总结如下:

  • 当b是奇数时,那么有 a^b = a * a^*(b-1)
  • 当b是偶数时,那么有 a^b = a^(b/2) * a^(b/2)
const int mod = 1e9 + 9;
long long qpow(long long x, long long y)
{
    long long  ret = 1;
    x = x % mod;
    while (y)
    {
        if (y % 2 == 1)	//如果为奇数次幂
            ret = (ret * x) % mod;
        y /= 2;
        x = (x * x) % mod;
    }
    return ret % mod;
}

但是这样算依然不够快,我们要知道—— “/”运算需要40个CPU时钟;“*”运算需要4个CPU时钟;“+-”一般需要2个CPU时钟,但是,位运算只要1个!

为了提高快速幂的效率和速度,我们可以将 y % 2 == 1 改为 y & 1;将 y /= 2 改为 y >>= 1 (y右移移位并赋值)。

const int mod = 1e9 + 9;
long long qpow(long long x, long long y)
{
    long long  ret = 1;
    x = x % mod;
    while (y)
    {
        if (y & 1)  // y % 2 == 1
            ret = (ret * x) % mod;
        y >>= 1;    // y /= 2 
        x = (x * x) % mod;
    }
    return ret % mod;
}

下面给大家介绍一下简单的移位运算:
1.右移运算符(>>)
例如:11的二进制形式为:1011,然后把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。则得到的最终结果是 0010。转换为十进制是 2。所以代码中 y >>= 1 的意思就是将二进制 y 右移移位并赋值,二进制下右移移位就是除以 2。

2. 按位与运算符(&)
按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。
例如:9&5 可写算式如下: 1001 & 0101 为 0001 ,可见 9&5=1。

猜你喜欢

转载自blog.csdn.net/SongXJ_01/article/details/104206771
今日推荐