快速幂 加 取余运算(题解)

洛谷上的题目:P1226 【模板】快速幂||取余运算

1.如何让计算机很快地求出a^b?

方法1:暴力循环

if(b==0)
  a==1;
while(int i=0;i<b-1;i++)
{
  a*=a;
}

(当然,如果是这样,肯定不能称得上是“快速”幂。暴力相乘的话,电脑要计算 b 次)

方法2:巧用二进制快速幂

如果用快速幂,计算次数在log2​(b) 级别,实用很多。

(1)把 a 自乘一次,就变成了 a^2 。然后把 a^2 再自乘一次就会变成 a^4 。然后是 a^8…… 乘n次后的结果是 a^{2^{n}}。

(2)a^xa^y = a^{x+y}

(3)b 的二进制:比如 b = (11)_{10}即 (1011)_{2} 。这就是十进制的 8,2,1。可那么 a^{11} = a^8 × a^2 × a^1

为啥要这样表示?因为我们要他通过自乘得到b次。而这个b我们恰好可以通过他的二进制分成几个数的和。比如11,分成8,2,1,这样恰好可以通过a的自乘得到。

过程

·拿到了 a,并且 b = 11。想求 a^{11}

·以电脑视角稍稍观察一下 b = 11,二进制下是 b = 1011b=1011。

·定义base。现在 base = a,表示a^1 = a。

·定义 ans,初值是 1

当然,如果最后要用二进制来做,可以用操作符巧妙判断b二进制最后一位

if(b & 1)
	ans *= base;

/* b & 1:
“&”即“按位与”。
x & y 是二进制 x 和 y 的每一位分别“与运算”的结果。
与运算,即两者都是 1 时才会返回 1,不然返回 0。
那么 b & 1

          二进制
b     =    1011
1     =    0001
b&1   =    0001

因为 1(二进制)的前面几位全都是 0,
即只有 b 二进制最后一位是 1 时,b & 1 才返回 1。
巧妙,而且很快。)*/

然后 basebase ,自乘一次,变成 a^2。

base *= base;

同时

b >>= 1;

所以就是这样

int quickPower(int a, int b)
{
	int ans = 1;
    int base = a;
	while(b > 0)
    {
		if(b & 1)
			ans *= base;
        base *= base;
		b >>= 1;
	}
	return ans;
}

取余

(m+n)moda=(mmoda+nmoda)moda

(m×n) \mod a = ((m \mod a) × (n \mod a)) \mod a(m×n)moda=((mmoda)×(nmoda))moda

然后把这个放到快速幂里面,减小运算时的数据

while(b > 0)
    {
		if(b & 1)
        {
			ans *= base;
            ans %= m;
    	}
		
        base *= base;
        base %= m;
		b >>= 1;
	}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值