快速幂运算(非大数)

快速幂顾名思义,就是快速算某个数的多少次幂。其时间复杂度为 O(log?N), 与朴素的O(N)相比效率有了极大的提高。

下面以3­16 为例:

一般运算方式是:

316 = 3*3*3*3……*3

这样的话需要运算15次

而快速幂运算的方式是:

316 = (32)8 = ((32)2)4 = (((32)2)2)2

这样的话只需要运算4次

不难看出,快速幂运算其实就是每次运算时把底数平方,指数减半,从而提高效率。

显然,当指数为奇数时,我们要作一些特殊处理:

以711为例:

711 = 710 * 7 = (72)5 * 7 = (72)4 * 72 * 7 = ((72)2)2 * 72 * 7

其实与前面的运算差异不大,当指数为奇数时,只需要从指数里取出1来单独运算即可。

以下为递归实现快速幂代码:

 1 #include <stdio.h>
 2 typedef long long int LL; //为long long int 定义别名 LL
 3 LL FastPower(LL a, LL b, LL c) //a为底数,b为指数,c用来存储单独运算的乘积
 4 {
 5     if(b == 0) //任何数的0次方都为1(0的0次方有争议,这里默认为1)
 6         return 1;
 7     else if(b == 1) //递归出口
 8         return a*c; //运算结束,返回结果
 9     else if(b%2 == 1) //当指数为奇数时
10         return FastPower(a*a, (b-1)/2, c*a); //从指数取出1来乘到c里存储起来,其他照常
11     else //当指数为偶数
12         return FastPower(a*a, b/2, c);
13 }
14 int main(void)
15 {
16     LL a, b;
17     //测试
18     while(~scanf("%lld %lld", &a, &b))
19         printf("%lld^%lld = %lld\n\n", a, b, FastPower(a, b, 1)); //c的初始值应为1而不是0
20     return 0;
21 }

运用上位运算稍微优化一下代码

 1 #include <stdio.h>
 2 typedef long long int LL;
 3 LL QPower(LL a, LL b, LL c)
 4 {
 5     if(!b)
 6         return 1;
 7     else if(b == 1)
 8         return a*c;
 9     else
10         return b&1 ? QPower(a*a, b-1>>1, a*c) : QPower(a*a, b>>1, c);
11 }
12 int main(void)
13 {
14     LL a, b;
15     while(~scanf("%lld %lld", &a, &b))
16         printf("%lld\n", QPower(a, b, 1));
17     return 0;
18 }

如有错误,欢迎指出

时间: 2025-01-02 06:47:00

快速幂运算(非大数)的相关文章

【分治】快速幂运算-递归与非递归方法

问题 Q: [分治]快速幂运算 时间限制: 1 Sec  内存限制: 128 MB提交: 14  解决: 9[提交][状态][讨论版] 题目描述 邪狼:“老大,好像还是不够油钱啊?”修罗王:“看来只好用我的独门绝技----能力增持术了.”邪狼:“听说能量增持数很霸道的?”修罗王:“没错,假设初始燃油能提供的能量为X,当我对它进行能量增持n秒后,该然后的能量将达到Xn”邪狼:“这么强大的技能啊,简直逆天了,不过怎么之前不见老大用过?”修罗王:“偶尔偷偷用几次没关系,经常用,燃油公司会找我麻烦的.”

POJ 1845 Sumdiv【同余模运算+递归求等比数列和+快速幂运算】

快速幂运算在第一次训练时候就已经遇到过,这里不赘述 同余模运算也很简单,这里也不说了,无非是(a+b)%m (a*b)%m 把m弄到里面变成(a%m+b%m)%m   (a%m*b%m)%m 今天学的最重要的还是递归二分求等比数列 题目大意是给出A和B,求A^B的约数和 解这个题,首先,对A进行素因子分解得到 (PI(pi^ai))^B 然后我们有约数和公式: 对A=PI(p1^k1) A的所有因子之和为S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^

快速幂运算

快速幂运算顾名思义,就是快速算某个数的多少次幂.其时间复杂度为 O(log?N), 与朴素的O(N)相比效率有了极大的提高. 以下以求a的b次方来介绍 把b转换成二进制数. 该二进制数第i位的权为 例如 11的二进制是1011 11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1 因此,我们将a¹¹转化为算 代码如下 int pow3(int a,int b) { intr=1,base=a; while(b!=0) { if(b&1) r*=base; base*=base; b>

[ACM] hdu 3923 Invoker (Poyla计数,快速幂运算,扩展欧几里得或费马小定理)

Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael can control the elements and combine them to invoke a powerful skill. Vance like Kael very much so he changes the map to make Kael more powerful. In

UVa 10006 快速幂运算

知识补充: 如果a和b关于m同于,那么(a - b )是m的整数倍. 负数取余运算:不同的语言有不同的方法,其中C和JAVA是按第一个数的符号确定结果的符号,C++则要依据系统而定. 取余运算的发展: 1.(a+b)%p=(a%p+b%p)%p 2.(a?b)%p=(a%p?b%p)%p 3.(a?b)%p=(a%p?b%p)%p 4.(ab)%p=((a%p)b)%p 费马定理:对于一个不能被p整除的数a: ap≡a mod p ap?1≡1 mod p 快速幂算法(求xn%mod): 有两种

快速幂运算模板

ll pow(ll a,ll b) //long long型 { ll ans=1; while(b!=0) { if(b%2==1) //if(b&1) ans=ans*a%mod;//如果是奇数次幂,因为b下面是除以2操作,会少一次乘,这里要提前乘上去. a=a*a%mod;//快速幂,每一次是上一次的平方倍 b=b/2; } return ans; } 分析: 将指数b看成二进制,b%2==1即判断当前b二进制最低位是否为1,是则将当前底数a与累积ans相乘,否则跳过.在每次循环中都将底数

基础快速幂运算

浅析快速幂 首先,举个例子(假设数据全为long long型). 例题:输入a,n, 求a的n次方(a > 0). 看到这个例题,肯定是思路滚滚来啊,不就是相当于n个a相乘吗?于是乎,就上代码了: #include<iostream> using namespace std; long long ans(long long &a, long long &n) { long long sum = 1; for (int i = 1; i <= n; i++) { su

小白详细讲解快速幂--杭电oj2035-A^B

Problem Description 求A^B的最后三位数表示的整数.说明:A^B的含义是“A的B次方” Input 输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理. Output 对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行. 简单的说这题就是要求高次幂,有两种方法可以实现. 第一总比较土鳖,每次乘完对1000取余也可以过. 我要讲的是第二种听起来很高大上的方法——快

fzoj--1683--矩阵快速幂

...起床了 先把这题给过了 还是今天凌晨留下来的.... 刚开始真sb啊 以为矩阵构造出来不能进行快速幂运算的 一定要借助单位矩阵..... 一般你构造出来的时候 2个矩阵的行列不是全都相等的  为了方便运算 我们可以空余位置默认为0 反正我是这样解决的 ....好像这个解决方法有点渣 我也不清楚... touch    me 1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 const i