题意:
给三个整数 a, b, S。
每次 1) a += b 或者 2) b += a
问经过若干次操作后,能否得到S
思路:
首先需要得到 ax + by = S 的正整数解系。
然后可以观察并且可以猜想。。。满足gcd(x, y) = 1 的解一定可以凑出S。。
注意long long可能溢出
LL a, b, s;
LL gcd(LL a, LL b)
{
return b == 0 ? a : gcd(b, a % b);
}
// 求解 a * n + b * m = gcd(n, m)
// 求得一组解 (x0, y0)
// 解系: (x0 + k * b / g, y0 - k * a / g)
LL ext_gcd(LL &a, LL n, LL &b, LL m)
{
if (m == 0) {
a = 1; b = 0;
return n;
}
LL d = ext_gcd(b, m, a, n%m);
b -= n / m * a;
return d;
}
int main() {
#ifdef _LOCA_ENV_
freopen("input.in", "r", stdin);
#endif // _LOCA_ENV
while ( cin >> a >> b >> s ) {
LL x, y, g;
if ( !a && !b ) {
if ( !s )
cout << "YES\n";
else
cout << "NO\n";
continue;
}
if ( !a ) {
if ( s % b == 0 )
cout << "YES\n";
else
cout << "NO\n";
continue;
}
if ( !b ) {
if ( s % a == 0 )
cout << "YES\n";
else
cout << "NO\n";
continue;
}
g = ext_gcd(x, a, y, b);
if ( s % g != 0 ) {
cout << "NO\n"; continue;
}
LL A = b / g, B = a / g;
x = ((s / g % A) * (x % A) % A + A) % A;
y = (s - x * a) / b;
int flag = 0;
while ( y > 0 ) {
if ( gcd(x, y) == 1 ) {
flag = 1; break;
}
x += A, y -= B;
}
if ( flag )
cout << "YES\n";
else
cout << "NO\n";
}
return 0;
}