Codeforce Round #554 Div.2 C - Neko does Maths
阿新 • • 發佈:2019-04-29
eof include gcd swa def 。。 mes fine 有關
數論 gcd
看到這個題其實知道應該是和(a+k)(b+k)/gcd(a+k,b+k)有關,但是之後推了半天,思路全無。
然而。。有一個引理:
- gcd(a, b) = gcd(a, b - a) = gcd(b, b - a) (b > a)
證明一下:
令 gcd(a, b) = c, (b > a)
則有 a % c = 0, b % c = 0
那麽 (a - b) % c = 0
令 gcd(a, b - a) = c‘, 假設c‘ != c
則有 a % c‘ = 0, (b - a) % c‘ = 0
則 (b % c‘ - a % c‘) % c‘ = 0, 所以 b % c‘ - a % c‘ = 0
所以 b % c‘ = 0
所以可以得出 c = c‘, 與假設矛盾, 則 c = c‘.
同理可得 gcd(b, a - b) = c
證畢。
然後我們要求最小的k,那就枚舉定值b-a的所有約數,看看a和b中小的那個數要湊成含這個約數的最小k是多少, 暴力找最大的lcm.
#include <bits/stdc++.h> // 9223372036854775807 #define INF 2333333333333333333 #define full(a, b) memset(a, b, sizeof a) using namespace std; typedef long long ll; inline int lowbit(int x){ return x & (-x); } inline int read(){ int X = 0, w = 0; char ch = 0; while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); } while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar(); return w ? -X : X; } inline ll gcd(ll a, ll b){ return a % b ? gcd(b, a % b) : b; } inline ll lcm(ll a, ll b){ return a / gcd(a, b) * b; } template<typename T> inline T max(T x, T y, T z){ return max(max(x, y), z); } template<typename T> inline T min(T x, T y, T z){ return min(min(x, y), z); } template<typename A, typename B, typename C> inline A fpow(A x, B p, C lyd){ A ans = 1; for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd; return ans; } int main(){ ll a, b, c; cin >> a >> b; if(a > b) swap(a, b); c = b - a; int n = (int)(sqrt(c) + 0.5); vector<int> v; for(int i = 1; i <= n; i ++){ if(c % i == 0) v.push_back(i), v.push_back(c / i); } int k = 0; ll ans = INF; for(int i = 0; i < v.size(); i ++){ int tmp = 0; if(a % v[i] != 0) tmp = v[i] - a % v[i]; ll r = lcm(a + tmp, b + tmp); if(r < ans) ans = r, k = tmp; } cout << k << endl; return 0; }
Codeforce Round #554 Div.2 C - Neko does Maths