快速幂 (递归/迭代)

本文介绍了快速幂算法的两种实现方式:递归和迭代。递归方法通过将指数n分为偶数和奇数情况来减少运算次数,而迭代方法利用二进制拆分指数,仅对二进制位为1的位置进行乘法操作。两种方法的时间复杂度均为O(log n),但迭代方法具有更低的空间复杂度O(1)。文章通过示例展示了算法的具体过程,并分析了它们的时间和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快速幂+递归

x 64 x^{64} x64 : x→ x 2 x^{2} x2 x 4 x^{4} x4 x 8 x^{8} x8 x 16 x^{16} x16 x 32 x^{32} x32 x 64 x^{64} x64 , 只需要把前一个的 x k x^k xk自乘一次
x 65 x^{65} x65: x→ x 2 x^{2} x2 x 4 x^{4} x4 x 8 x^{8} x8 x 16 x^{16} x16 x 32 x^{32} x32 x 65 x^{65} x65 , 在 x 32 x^{32} x32自乘一次后还要再乘一个x
x n x^{n} xn: ①若n为偶数, x n x^{n} xn = x n / 2 x^{n/2} xn/2 * x n / 2 x^{n/2} xn/2 = x ( n / 2 ) ∗ 2 x^{(n/2)*2} x(n/2)2 ; ②若n为奇数, x n x^{n} xn = x n / 2 x^{n/2} xn/2 * x n / 2 x^{n/2} xn/2 * x,(其中 x n / 2 x^{n/2} xn/2中n/2 为n/2向下取整后的数,如65/2=32.5,向下取整为32)

double myPow(double x, long long int n)
{
    if(n == 0) return 1.0;
    double y = myPow(x, n/2);
    return n%2==1 ? y*y*x : y*y;
}
int main()
{
    double x; int n;
    cin >> x >> n;
    long long int N = n;

    double ans = N >= 0 ? myPow(x, N) : 1.0/myPow(x, -N);
    cout << ans << endl;
    return 0;
}

输入:2.00000 10
输出:1024.00000

输入:2.10000 3
输出:9.26100

输入:2.00000 -2
输出:0.25000

复杂度分析

  • 时间复杂度:O( l o g   n log\ n log n), 即为递归的层数
  • 空间复杂度:O( l o g   n log\ n log n), 即为递归的层数。这是因为递归的函数调用会使用栈空间

快速幂+迭代

x 11 x^{11} x11 : 11的二进制:1011,于是 x 11 x^{11} x11 = x ( 2 0 + 2 1 + 2 3 ) x^{(2^0 + 2^1 + 2^3)} x(20+21+23) = x ( 2 0 ) x^{(2^0)} x(20) * x ( 2 1 ) x^{(2^1)} x(21) * x ( 2 3 ) x^{(2^3)} x(23) = x * x 2 x^{2} x2 * x 8 x^{8} x8, 只要分别求 x i x^i xi再相乘,不用将x连乘11次

double myPow(double x, long long int n)
{
    double ans = 1.0, tmp = x;
    while(n)
    {
        if(n%2 == 1)  // 指数二进制末尾为1
            ans *= tmp;
            
        tmp *= tmp;  
        n/=2;  // 舍去二进制最低位
    }
    return ans;
}
int main()
{
    double x; int n;
    cin >> x >> n;
    long long int N = n;

    double ans = N >= 0 ? myPow(x, N) : 1.0/myPow(x, -N);
    printf("%.5f\n", ans);
    return 0;
}

关于tmp*=tmp
tmp最初等于x,
随着n右移舍去最低位,tmp也发生变化: t m p tmp tmp t m p 2 tmp^2 tmp2 t m p 4 tmp^4 tmp4 t m p 8 tmp^8 tmp8 →……
当n的二进制最低位是1的时候,即if(n%2 == 1) 成立时,tmp就可为ans做出贡献。

x 11 x^{11} x11时,tmp: x x x x 2 x^2 x2 x 4 x^4 x4 x 8 x^8 x8 , 在这个过程中并不是每一个tmp值都会被乘入ans,我们只需要 x x x x 2 x^2 x2 x 8 x^8 x8,即11的二进制为1的位置时的数。

复杂度分析

  • 时间复杂度:O( l o g   n log\ n log n), 即为对n进行二进制拆分的时间复杂度
  • 空间复杂度:O(1)

😉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值