这题题意灰常清楚不说了。
解法:可知需要用扩展欧几里德,但是并不是所有的x,y都能取得到的,找规律可得必须要互质。。为啥是互质我也不知道如何证明。。据说是因为辗转相减不是互质的无法得出一个a或者一个b,这题难度就在于会超long long,那么是在哪里会超呢?。在于算出一个x,y之后,大多数人肯定就直接乘上了s/gcd了。我也是。。想想,如果gcd是1,那么在数据大的时候必定会超,所以要取模,比如x,对b/gcd取模,然后乘上s/gcd对于b/gcd取模,这样是不会超long long的,如果x小于等于0就再加上b/gcd,y就通过s/gcd-x*a/gcd再除以b/gcd就可以算得了,这样的解就是x>0的第一个解,然后就判断gcd(x,y)是否等于1,x += b/gcd,y-=a/gcd,遍历到y<0结束,如果没有则是no,不然就是yes。
AC代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll __int64
#define NMAX 1000
void gcd(ll a, ll b, ll &d, ll &x, ll &y)
{
if(!b){d = a; x = 1; y = 0;}
else{gcd(b,a%b,d,y,x);y -= x*(a/b);}
}
ll ggcd(ll a,ll b)
{
if(!b) return a;
else ggcd(b,a%b);
}
int main()
{
#ifdef GLQ
freopen("input.txt","r",stdin);
// freopen("o.txt","w",stdout);
#endif // GLQ
ll a,b,s,A,B;
while(~scanf("%I64d%I64d%I64d",&a,&b,&s))
{
if(s < min(a,b))
{
printf("NO\n");
continue;
}
if((a == 1 && s > b)||(b == 1 && s > a)|| a == s || b == s)
{
printf("YES\n");
continue;
}
if(a == 0 && b == 0)
{
printf("NO\n");
continue;
}
if(a == 0)
{
if(s%b == 0) printf("YES\n");
else printf("NO\n");
continue;
}
if(b == 0)
{
if(s%a == 0) printf("YES\n");
else printf("NO\n");
continue;
}
ll x,y,gg,w;
gg = ggcd(a,b);
// cout<<gg<<endl;
if(s%gg)
{
printf("NO\n");
continue;
}
A = a/gg;
B = b/gg;
gcd(A,B,w,x,y);
x = (s/gg)%B*(x%B);
x %= B;
if(x <= 0) x += B;
y = (s/gg - A*x)/B;
// cout<<x<<" "<<y<<endl;
int flag = 0;
while(y > 0)
{
// cout<<x<<" "<<y<<endl;
if(ggcd(x,y) == 1)
{
flag = 1;
break;
}
x += B;
y -= A;
}
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}