来!咱彻底扔掉公式、扔掉难懂术语 ,用掰手指头数数的方式,讲到你秒懂!
cpp
LL qpow(LL a,LL b,int mod)
{
LL tmp=a;
LL ans=1;
while(b){
if(b&1) ans=(ans*tmp)%mod;
b>>=1;
tmp=tmp*tmp%mod;
}
return ans;
}
先定一个超简单目标:算 
是什么?
本来是:2×2×2×2×2
但我们换个偷懒拆法:5=1+4所以:=
*
只需要乘 2 个大数,不用乘 5 次!
现在看:5 的二进制是 101
从右边往左边 看这三个数字:1 0 1对应:最右边第一个数:1 → 对应 中间第二个数:0 → 对应
最左边第三个数:1 → 对应
规则超简单:✅ 数字是 1 :这个数要留下来相乘❌ 数字是 0:这个数直接扔掉,不乘
回到代码里的 b & 1
b & 1 作用:只看当前最右边那一个数字是啥
第一轮:b=5(二进制 101)
最右边是 1👉 按照规则:要乘!把当前底数塞进答案里
第二轮:b 往右挪一位(变成 10)
最右边是 0👉 按照规则:不要!啥也不乘,跳过
第三轮:b 再往右挪一位(变成 1)
最右边是 1👉 按照规则:要乘!再塞一次
再看 tmp(底数)在干嘛
tmp 一直在变大:2 → 4 → 16刚好就是我们要的:,
,
每看一位二进制,就对应一个 tmp:位是 1 → 乘这个 tmp位是 0 → 丢这个 tmp
终极大白话总结
b & 1 就是在问一句话:现在最右边这个二进制小格子里,写的是 1 还是 0?
- 写 1:这一份数字我要,乘进去
- 写 0:这一份数字我不要,直接扔
就这么简单!没有任何高深数学!