欧几里得算法与扩展欧几里得算法
欧几里得算法
已知a和b,求出\(gcd(a,b)\)
时间复杂度\(O(\log n)\)
\(gcd(a,b)*lcm(a,b)=a*b\)
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
//优化
int gcd(int a,int b){
if(a==0) return b;
if(b==0) return a;
if(a==b) return a;
if(a>b) return gcd(a%b,b);
return gcd(a,b%a);
}
模板题:hdu2104 hide handkerchief
扩展欧几里得算法
求出所有的x,y,使得对于给定的a,b,满足\(ax+by=c\)
时间复杂度\(O(\log n)\)
当且仅当\(gcd(a,b)|c\)时,存在整数解x,y
所以exgcd可以求解方程\(ax+by=gcd(a,b)\)
\(bx_1+(a\%b)y_1=gcd(b,a\%b)\)
\(bx_1+(a-b\lfloor\frac{a}{b}\rfloor)y_1=gcd(a,b)\)
\(ay_1+b(x_1-\lfloor\frac{a}{b}\rfloor y_1)=gcd(a,b)\)
所以原方程中,\(\left\{\begin{aligned}x=y_1\\y=x_1-\lfloor\frac{a}{b}\rfloor y_1\end{aligned}\right.\)。通过递归求出\(x_1,y_1\),可以得到x,y
原方程的解集:\(\{(x,y)|x=x_1+k*b/gcd(a,b),y=y_1-k*a/gcd(a,b),k\in z\}\)
void exgcd(int a,int b,int& x,int& y){
if(!b) {y=0;x=1;return;}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
模板题:hdu2669 Romantic