小凯的疑惑(扩展欧几里得)

小凯的疑惑 

a , x , b , y , gcd(a,b)   扩展欧几里得啊!!!


对于任何k(k为正整数)  一定存在x,y 满足 ax+by=k;

想想扩展欧几里得 ax+by=gcd(a,b)=1 是一定有解的

设ax+by=gcd(a,b)=1的解为

(x0,y0) 满足(x0>=0,y0<0) (x0',y0') 满足(x0'<0,y0'>=0)那么k*x0 , k*y0 就是原方程的一组解


对于合法的数k,可以表示为 k=a*x1+b*y1(x1>=0,y1>=0)

我们要找最大的k使k-1不合法

对于不合法的数k-1,可以表示为

k-1=a*x1+b*y1-(a*x0+b*y0)=a*(x1-x0)+b*(y1-y0) ...1

或k-1=a*(x1-x0')+b*(y1-y0')  ...2

对于1 y0<0 所以y1-y0>0 只要x1-x0<0 就没搞

对于2 x0'<0 所以x1-x0'>0 只要y1-y0'<0就没搞

所以如果要肯定没搞,两个都要满足

所以x1=x0-1,y1=y0'-1 两个都没搞, 而且k最大

ans=(x0-1)*a+(y0-1)*b-1


我们学到了什么

1.看范围  --1e9,互质等字眼,我们要用O(logn)的扩展欧几里得

2.转化问题  --找最大的k使k-1不合法

3.式子标准化  --将k-1用a*(x1-x0)+b*(y1-y0)的形式表示

4.探究不合法的条件  --x1-x0<0,y1-y0'<0

5.贪心找最值  --x1=x0-1,y1=y0-1


void exgcd(int a,int b)
{
	if(b==0) g=a,x=1,y=0;
	else{
		exgcd(b,a%b);
		int x1=y,y1=x-a/b*y;
		x=x1,y=y1;
		printf("%d*(%d)+%d*(%d)=%d\n",a,x,b,y,g);
	}
}

void solve()
{
    exgcd(a,b);
    x=(x+b)%b,y=(y+a)%a;
    cout<<(x-1)*a+(y-1)*b;
}

猜你喜欢

转载自blog.csdn.net/sslz_fsy/article/details/81782313