zoukankan      html  css  js  c++  java
  • Codeforces Round #554 Div.2 C

    数论 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;
    }
    
  • 相关阅读:
    贝叶斯定理经典案例
    java 简单秒杀
    menu JPopupMenu JTabbedPane
    java String matches 正则表达
    gg mirror
    后台计时
    css 标题
    ajax dataType
    jQuery ajax
    java null 空指针
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/10792309.html
Copyright © 2011-2022 走看看