快速求幂

快速幂在算指数时是很高效的,他的基本原理是二进制。

如果要算

2^5,可以直接2*2*2*2*2

但是如果要算

3^999,指数N太大,计算太慢,所以有一种快速的解法。

@@@@@@@@@@@@@@@@@@@@@@@@

以3^21为例。

2^21=(2^16)×(2^4)×(2^1)

21的二进制可以写成(10101)----------------而10101可以写成1*2^4+0*2^3+1*2^2+0*2^1+1*2^0

可以明显看出, 每一个香对应着上边的指数。   2^4=16 2^2=4; 2^0=1   其他项为0;

(具体推理有空再写)

@@@@@@@@@@@@@@@@@@@@@@@@

再找一个例子

2^13

13=(1101),-----------------1*2^3+1*2^2+1*2^0, 指数分别是8,4,1;

2^13=2^(8+4+1)

///////A^(一个二进制数如101010)=A^(100000)*A^(00000)*A(1000)*A^(000)*A^(10)*A^(0)=A^(2^5)*A^(2^3)*A^(2^1)

@@@@@@@@@@@@@@@@@@@@@@@@

所以要计算X^N,现将N变成二进制,然后依次计算二进制的每位的值(如果为二进制位为0不计算)

@@@@@@@@@@二进制的计算@@@@@@@@@@@@@@

计算13的二进制,对其除2取余,记录余数。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

代码如下:

 1 int pow_n(int x, int n)
 2 {
 3     int pw = 1;
 4
 5     while (n > 0) {
 6         if ((n % 2) == 1)
 7             pw *= x;
 8         x *= x;
 9         n /= 2;
10
11     }
12     return pw;
13 }

计算2^13的步骤就是:

13=(1101)
n%2, 最低位是1, 所以把这部分累乘到pw中,(pw=2^1)x自乘后变成x^2,n=n/2;
n 的这一位是0,所以if不成立,不执行累2乘,    x自乘后变成x^4,n=n/2;
n 的这一位是1,(pw=2^1*2^4),所以累乘到pw中。x自乘后变成x^8,n=n/2;
n 的这一位是1,(pw=2^1*2^4*2^8)所以累乘到pw中。

这是快速求幂的思想,把指数n 分解为2的幂次的和,利用自乘计算x 的(2的幂次)次方, 然后根据需要决定是否累乘相应的幂次。

这样可以把O(n)次乘法缩短到O(logn)次乘法,实现快速计算。

n=n/2和 (n%2==1)是检查指数n 的某个二进制位是否是1的手段。

时间: 2024-12-25 13:21:14

快速求幂的相关文章

A sequence of numbers(快速求幂)

题目描述 Xinlv wrote some sequences on the paper a long time ago, they might be arithmetic or geometric sequences. The numbers are not very clear now, and only the first three numbers of each sequence are recognizable. Xinlv wants to know some numbers in

NYOJ--102--次方求模(快速求幂取模)

次方求模 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 求a的b次方对c取余的值 输入 第一行输入一个整数n表示测试数据的组数(n<100)每组测试只有一行,其中有三个正整数a,b,c(1=<a,b,c<=1000000000) 输出 输出a的b次方对c取余之后的结果 样例输入 3 2 3 5 3 100 10 11 12345 12345 样例输出 3 1 10481 1 /* 2 Name: NYOJ--102--次方求模 3 Copyright: ?

快速求幂运算笔记

如何快速求x得n次方呢? 首先C++里面有个pow如何实现呢?自己查查,里面使用double,肯定更麻烦,还有jianzhi 我们会顺手写下 int res=1; for(int i=1;i<=n;i++) { res*=x; } 学习一下快速幂,logn内计算出来,使用N的二进制,只需要logN就可以计算. 正要的就是计算每个为1对应的基数.列入: 11是多少?是二进制的话,就是1*2^1+1 那么x^(11)呢,两个1对应的基数是多少呢?低位1对应的是X,高位1对应的是X^2,因此,就是位于

快速求幂 POW优化

#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; int pow(int x, int n) { int result = 1; while (n > 0) { if (n % 2==1) result *= x; x *= x; n /=2 ; } return result; } int main()

快速求幂模

今天我要介绍的是快速求幂模,在开始介绍之前,我们先看看如何快速求幂.这里我要介绍的是二分求幂. 二分求幂的原理如下: 下面,我们将这个公式转换成代码: int cifang(int a,int n)//返回值是a的n次方 { int res=1;//任何数的0次方都等于1,所以初始化为1 while(n != 0) { if(n%2 == 1)//如果n是奇数 res *= a;//就要多乘一次,即res = res*a; a = a*a; n /= 2;//二分,即n = n/2 } retu

非递归快速求幂算法

快速求正整数次幂,当然不能直接死乘.举个例子:3 ^ 999 = 3 * 3 * 3 * … * 3直接乘要做998次乘法.但事实上可以这样做,先求出2^k次幂:3 ^ 2 = 3 * 33 ^ 4 = (3 ^ 2) * (3 ^ 2)3 ^ 8 = (3 ^ 4) * (3 ^ 4)3 ^ 16 = (3 ^ 8) * (3 ^ 8)3 ^ 32 = (3 ^ 16) * (3 ^ 16)3 ^ 64 = (3 ^ 32) * (3 ^ 32)3 ^ 128 = (3 ^ 64) * (3

二分求幂(快速求幂,二进制求幂)

二分求幂, 非递归求法(二进制求法): 比如 2^5就是5个2相乘,按照5的二进制求 3^10就是8个3相乘,再2个3相乘. 处理幂的二进制,具体实现代码如下: long long quickmulti(long long a,long long b) { long long res=1; while(b) { if(b&1) //如果最后一位为1,则res*=a; res*=a; a*=a; //a*=a b>>=1; //b%=2 } return res; }

快速求幂运算

1 #include <stdio.h> 2 #include <math.h> 3 //递归算法 4 int recursion(int a,int b) 5 { 6 int tem = 1; 7 if(b==0)return 1; 8 else if(b==1)return a; 9 tem = recursion(a,b>>1); 10 tem = tem*tem; 11 if(b&1) tem = tem * a; 12 return tem; 13 }

北大ACM3641——Pseudoprime numbers~~快速求幂法

这一题,主要是快速求幂的方法的应用. 可以看看快速求幂方法的原理:http://blog.csdn.net/qq_25425023/article/details/44316463 题目的大概意思是: 输入两个数p,a,p为素数,则直接输出no,否则判断a^p % p == a?等于就yes,不等于就no. 理解了题目的意思,就很容易了. 下面的是AC代码: #include <iostream> #include <cstdio> using namespace std; int