扩展欧几里得算法;
补充两个常识(2333333)
【某定理】:计算两个正整数的最大公因子时,所需的除法次数不会超过较小的那个数的10进制的5倍;
【补充】:a和b 互素的条件,gcd(a,b)=1; 存在整数x,y,使得xa+yb=1.
= =以下绝大部分是结果/定理= =【T^T搞得我累死了,想看讲解的请关闭并点击【详解】】
利用扩展GCD求解一个不定方程。
定义: gcd=Gcd(a,b)=xa+yb;
我们有一个不定方程:a*x + b*y = gcd (有解),
我们可以找出一个通解,
x= x0 + (b/gcd)*t
y = y0-(a/gcd)*t
我们是否可以从最终状态反推到最初的状态呢?
两个相邻的状态之间:
gcd = b*x1 + (a-(a/b)*b)*y1 //a%b = a- (a/b)*b
= b*x1 + a*y1 – (a/b)*b*y1
= a*y1 + b*(x1 – a/b*y1)
所以--代码:【强行知道是这么回事】
int exgcd(inta,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=exgcd(b,a%b,&x,&y);
int temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
想要练习一波 求解一个不定方程的(两题都是裸的):
ZOJ 3609http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4712
HDU2669 http://acm.hdu.edu.cn/showproblem.php?pid=2669
int exgcd(inta,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=exgcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int x,y;
int a,m;
scanf("%d%d",&a,&m);
if(exgcd(a,m,x,y)==1)
{
// printf("x=%d\n",x);
// printf("y=%d\n",y);
if(x<=0)
{
x+=m;
}
cout<<x<<endl;
//算法中的通解x0可以理解成最小的x(如果有些问题到最大是不是ax,by互换一下(by+ax=1)就好了呢?23333)
//由于问题的特殊性,有时候我们得到的特解 x0 是一个负数
}
else
printf("Not Exist\n");
}
return 0;
}