快速幂取模
快速幂
个人理解的快速幂其实就是把a^b的幂给拆开,把一件复杂的事情拆分为多件事情,而计算机可以同步做多件事情而时间就比做一件复杂的事情节省了很多。而快速幂利用了位运算恰好可以将幂给拆开。如果对位运算不了解的可以先了解位运算相关知识,否则会想我开始一样看不懂快速幂的公式。
int Pow(int a,int b) //a^b
{
int ans=1;//最终的ans为a^b的值
int base=a;//因为快速幂的原理就是利用二进制将b拆开,从而得到很多上面所说的简单公式。
while(b)
{
if(b&1)//此处涉及位运算,大概的意思是在b的二进制式子中遇到1就将答案自乘上a的某次方
ans*=base;
base*=base/**此处理解有些困难,举个栗子便于理解。如果是求2^10,那我们可以拆成2^(2^1)*2^(2^3),因此10实际上拆分成为了2^1和2^3这里我们将2看做x,1、3都看成y。如果base代表的是y那么base*=x,但是base在上面的代码中代表的是x^y,所以是base*=base,中间还有一个平方关系。**/
b>>=1;//简单的向右移一位
}
return ans;
}
快速幂取模
相信上面的代码通过注释已经变得通俗易懂,快速幂就是将幂给拆开分到一个乘式中,而二进制刚好可以做到这点。接下来的取模可能和你未接触时所想的公式完全不同,但是还是能理解的。
最基础的式子:(ab) mod c=((a mod c)(b mod c)) mod c
刚接触快速幂取模时,我想当然的就以为这个等式的后面应该就是(a mod c)*(b mod c),但回想起来确实容易理解,虽然a mod c的值和b mod c的值都比c小,但是它们相乘就不一定了,所以最后还要加一个mod c。
接下来就是由它推导出来的式子了:
(a^b) mod c=(a mod c)^b mod c
这个式子推导原理和上面一样,a mod c的b次方可能大于c了所以还要加mod c
接下来就是令人期待的快速幂取模的代码了
int pow_mod(int a,int b,int c)
{
int ans=1;
int base=a%c;
while(b)
{
if(b&1)
ans=(ans*base)%c;//相当于括号外取模
base=(base*base)%c;//相当于括号内的取模
b>>=1;
}
return ans;
}
代码千变万化,相信在你理解这些之后能有更好的代码!(代码来源于其他博客0.0)