题面
大意是正整数a,b互素,求最大的k,使得ax+by=k(x>=0,y>=0)无解,即不能用a,b凑出k。
思路
根据上面提取出的公式,可以很快联想到exgcd求不定方程,实际上这也确实是一种解法,但本人太菜,选择了一种更为通俗的方法:
........本文中将一个数能被凑出称为被覆盖..........
不妨设b>a, 将实数数轴划分为长度为a的若干段,则每段中至多有一个b的倍数,显然对于x=c1*a+c2*b来说,c1的大小不影响x在所属段中的相对位置。只有c2即b的个数会影响其位置,而对数轴上的某一个位置来说,只要在当前段中能被凑出,以后每一段中的此位置都可以通过+a被覆盖。问题转化为求第一个将长度为a的数段完全覆盖的位置。设加入x=c3*b后,该段能被完全覆盖,则x'=x-a位置一定未被覆盖。且x'所在段中其他数一定已被覆盖。所以x'即为所求。
可以发现b的个数每增加1,就会覆盖段中的一个新位置(如果覆盖的是旧的位置,而此时此段还未被完全覆盖,那么b的覆盖位置会形成一个循环,此题即无解,对应的是a,b不互质的情况)当q*b%a==0时,x1=n*b与x2=(n+q)*b在段中的相对位置相同,当q最小时,q=a/(gcd(a,b),因此第一个重复的位置一定是a/(gcd(a,b)*b)。a,b互质时,第一个重复位置即为a*b。所以第一个完全覆盖的位置为x=(a-1)*b。因此x'=x-a=a*b-a-b。至此可以O(1)得出答案。
也可以换一种思路感性理解:因为每次覆盖的位置不同,长度为a的段要覆盖a次,因为0*b也算一次,所以最大的位置为x=(a-1)*b,x'=x-a=a*b-a-b。
建议不必看代码了。
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define pi pair<int,int> 4 using namespace std; 5 int main(){ 6 int i,j,n,m; 7 ll k,l; 8 scanf("%lld%lld",&k,&l); 9 k=k*l-k-l; 10 printf("%lld",k); 11 return 0; 12 }