c++入门必学算法之快速幂思想及实现

以下是“C++入门必学算法之快速幂思想及实现”的攻略。

教程概述

快速幂是一种计算幂运算(类似于指数运算)的高效算法。在求解幂运算时,我们通常是采用暴力方法进行连乘,这样的时间复杂度为 $O(n)$,效率较低。而快速幂算法能够在 $O(log_2(n))$ 的时间复杂度内完成幂运算,提高了计算效率。

在本教程中,我们将会介绍快速幂算法的思想和具体实现方法,并提供两条示例说明,帮助大家更好地理解此算法。

快速幂算法思想

快速幂算法的思想是将指数 $n$ 转化为二进制数形式,通过对于每一位的计算结果进行累乘的方式求解幂运算。

例如,当要计算 $a^n$ 时,我们可以将指数 $n$ 转化为二进制数的形式,然后对于每一个非零二进制位 $i$,都计算 $a^{2^i}$,并将结果累乘。例如,当 $n=13$ 时,二进制形式为 $1101$:

$$
a^{13} = a^{2^0} \times a^{2^2} \times a^{2^3}
$$

尽管看起来需要进行 $log_2(n)$ 次计算,但事实上每一次计算都是上一次计算结果的平方,因此在快速幂算法中,只需要使用循环和累乘和平方运算,即可完成高效的幂运算。

快速幂算法实现

以下是快速幂算法的具体实现过程。

long long qmi(long long a, long long b, long long p) {
    long long res = 1 % p;
    while(b) {
        if(b & 1) res = res * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return res;
}

函数 qmi 用于计算快速幂运算。

其中,a 表示底数,b 表示指数,p 表示模数。

函数从初始值 res=1 开始循环,每次将指数 $b$ 与 1 做位运算,如果为 1,则将底数乘到结果中,否则不做任何操作。然后对底数进行平方,将指数右移一位,继续循环,直到指数为 0。最后返回结果即可。

示例说明

示例一:求幂模运算

接下来,我们给出一个示例,使用快速幂算法进行幂模运算。

假如我们需要计算 $2^{123456789}$ 除以 $987654321$ 的余数,直接进行连乘显然不可行,此时可以使用快速幂算法来进行快速计算。

首先,我们对 $123456789$ 进行二进制转化。可以得到:

$$
123456789_{10}= 1110101101110111100111010101_{2}
$$

然后使用快速幂算法即可:

long long a = 2, b = 123456789, p = 987654321;
cout<<qmi(a, b, p)<<endl;

输出结果为:

131176846

示例二:使用快速幂算法求斐波那契数列

我们可以用快速幂算法来求解斐波那契数列的第 $n$ 项,而不需要使用递归方法求解大量重复子问题。

斐波那契数列的公式如下:

$$
F_n=F_{n-1}+F_{n-2} \ \ (n>=2,F_0=0,F_1=1)
$$

假设我们需要求解斐波那契数列的第 $10$ 项 $F_{10}$。

使用快速幂算法,可以极大地缩短计算时间复杂度。具体实现如下:

long long a = 1, b = 1, p = 1e9 + 7;
for(int i = 2; i <= 10; i++) {
    int t = b;
    b = (a + b) % p;
    a = t;
}
cout<<b<<endl;

在循环中,我们从 $F_2$ 开始,每次将 $b$ 更新为 $F_{i+1}$,$a$ 更新为 $F_i$(具体原因是为了便于计算),然后通过斐波那契数列的公式进行计算。最终我们能够得到斐波那契数列的第 $10$ 项:

55

总结

本教程主要介绍了快速幂算法的思想和使用方法,并提供了两个示例进行说明。在实际的编程中,快速幂算法具有广泛的应用价值,能够用于高精度计算、求解幂模运算、求解斐波那契数列等问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++入门必学算法之快速幂思想及实现 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • Qt QDateTime计算时间差的实现示例

    针对“Qt QDateTime计算时间差的实现示例”的完整攻略,我将从以下几个部分进行讲解: QDateTime类的概述 计算时间差的方法 示例说明 1. QDateTime类的概述 QDateTime是Qt中用来提供日期和时间值的类,它继承自QDate和QTime类。QDateTime类的主要成员函数有date(),time(),addSecs()等,可以…

    C 2023年5月23日
    00
  • Vue SSR 即时编译技术的实现

    Vue SSR即时编译技术指的是在服务端,即时将Vue组件转换为HTML字符串的技术。下面是详细的实现攻略: 前置条件 首先需要确保你已经熟练掌握了Vue的基础知识,同时也要了解Vue SSR的原理和实现方式,以及Node.js相关的知识。 实现步骤 步骤一:安装依赖 首先,在项目中安装必要依赖: yarn add vue vue-server-render…

    C 2023年5月23日
    00
  • C++如何判断一个数字是否为质数

    下面是C++判断一个数字是否为质数的完整攻略,包含两条示例说明。 什么是质数 在数论中,质数是指除了 1 和本身之外,不能被其它正整数整除的数。比如,2、3、5、7、11、13等是质数,而4、6、8、9等不是质数。 C++中判断一个数字是否为质数 C++中判断一个数字是否为质数的方法一般是通过判断这个数是否能被除了1和它本身之外的其它数整除。这种判断方法比较…

    C 2023年5月23日
    00
  • C语言实现全排列算法模板的方法

    C语言实现全排列算法,是一个经典的算法问题,其思路也很简单。下面是实现全排列算法的详细攻略。 问题背景 给定长度为n的数组arr,将arr进行全排列。 也就是说,对于arr中的任意两个元素a和b(a不等于b),排列结果中a和b的相对位置可能不同。 解题思路 我们可以按以下步骤来实现全排列算法。 首先从数组的第一个元素开始,将其与后面的所有元素交换位置 交换后…

    C 2023年5月22日
    00
  • vue-cli使用stimulsoft.reports.js的详细教程

    下面是“vue-cli使用stimulsoft.reports.js的详细教程”的完整攻略,包含两个示例: 1. 环境准备 在开始之前,需要确认电脑已经安装了以下软件: Node.js npm Vue CLI 如果没有安装,可以到官网下载安装对应版本。安装完毕后,打开命令行工具,输入以下命令进行版本确认: node -v npm -v vue –versi…

    C 2023年5月23日
    00
  • C++11中std::future的具体使用方法

    下面是详细讲解C++11中std::future的具体使用方法的完整攻略。 什么是std::future? 在C++11中,std::future是C++标准库中的一个异步计算和延迟计算结果的类。它可以通过一个异步操作返回一个异步计算结果、异常或者延迟结果。std::future的设计遵循了“promise-future”模式,一个地方产生异步结果,另一个地…

    C 2023年5月22日
    00
  • C语言使用setjmp和longjmp实现一个简单的协程

    下面是C语言使用setjmp和longjmp实现一个简单的协程的完整攻略。 什么是协程 协程是一种并发编程模型,可以看做是一种用户空间的轻量级线程。协程特点是占用资源少,切换代价低,不需要线程上下文切换的开销,仅通过自己写的切换机制进行上下文切换。由于协程不需要访问操作系统资源,因此基本不会发生阻塞的现象,其在I/O密集型任务中具有很好的应用前景。 使用se…

    C 2023年5月24日
    00
  • C++如何将vector数字写入到txt文件中

    C++ 中可以使用 fstream 类来进行文件操作,包括读取和写入操作。在将 vector 数组写入文本文件中时,需要打开一个输出文件流,然后逐个将 vector 数组中的元素写入文件中即可。 以下是代码示例: 示例一 #include <fstream> #include <vector> #include <iostrea…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部