小凯的疑惑 / [蓝桥杯2013省]买不到的数目

题面

     点这里

         大意是正整数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 }
View Code
原文地址:https://www.cnblogs.com/jstcao/p/14041445.html