1.最大公约数与最小公倍数
int Gcd(int a,int b)//快速求a,b的最大公约数
{
int r;
while(b)
{
r=a%b;
a=b;
b=r;
}
return a;
}
int lcm(int a,int b)//快速求a,b的最小公倍数
{
return a*b/Gcd(a,b);
}
这里的Gcd是非递归的,总所周知递归效率明显不如非递归,虽然递归的写起来方便,直接 return b?Gcd(b,a%b):a;
2.快速积与快速幂
int FastMul(int a,int b)//快速积 a*b
{
int ans=0;
while(b)
{
if(b&1)
ans=ans+a;
a=a+a;
b>>=1;
}
return ans;
}
int FastExp(int a,int b)//快速幂 a^b
{
int ans=1;
while(b)
{
if(b&1)
ans=ans*a;
a*=a;
b>>=1;
}
return ans;
}
这里是利用二进制,将b转化为二进制在计算,比如求 3*93,a=3,b=93=(1011101)(二进制)=1*2^6+0*2^5+1*2^4+1*2^3+1*2^2+0*2^1+1*2^0,所以a*b=3*2^6+3*2^4+3*2^3+3*2^2+3*2^0,函数计算时是从后往前计算的,所以每次都判断b的二进制的最后一位是不是1,即if(b&1),如果是的话就加上a,然后a每次都要乘以2,因为例如前面的3*93,计算时是从3*1*2^0+3*0*2^1+3*1*2^2+......+3*1*2^6,不看0和1的话,后一项都是前一项的二倍,如果对应的二进制的位置为1就加上,否则不加,b每次都要右移一位,因为if(b&1)是判断b的二进制的最后一位是不是1。
快速幂的思路和快速积差不多,好好理解一下快速积的算法。
3.快速积取模与快速幂取模
int ModMul(int a,int b,int n)//快速积取模 a*b%n
{
int ans=0;
while(b)
{
if(b&1)
ans=(ans+a)%n;
a=(a+a)%n;
b>>=1;
}
return ans;
}
int ModExp(int a,int b,int n)//快速幂取模 a^b%n
{
int ans=1;
while(b)
{
if(b&1)
ans=ModMul(ans,a,n);
a=ModMul(a,a,n);
b>>=1;
}
return ans;
}
思路就是前面的2.快速积与快速幂,只是每次求完都要取模。