来自挑战程序设计竞赛2.6 数学问题的解题窍门
1.欧几里得算法
求解最大公约数,时间复杂度在O(log max(a,b))以内,可以看出,辗转相除法是非常高效的
int gcd(int a,int b)
{
return (b==0)?a:gcd(b,a%b);
}
2.扩展欧几里得算法
求解方程a*x+b*y=gcd(a,b),a、b、x、y均为整数,时间复杂度和辗转相除法是相同的,函数返回gcd(a,b)。
int gcd(int a,int b)
{
return (b==0)?a:gcd(b,a%b);
}
int extgcd(int a,int b,int& x,int& y)
{
int d=a;
if(b!=0){
d=extgcd(b,a%b,y,x);
y-=(a/b)*x;
}
else{
x=1;
y=0;
}
return d;
}
3.素数测试
//素性测试O(√n)
bool is_prime(int n)
{
for(int i=2;i*i<=n;i++){
if(n%i==0) return false;
}
return n!=1;//n等于1是例外
}
//约数枚举O(√n)
vector<int> divisor(int n)
{