poj2115(extend gcd + 逆元)

作者: sugar_coated | 来源:发表于2016-10-24 17:39 被阅读17次

    题意:给你A、B、C、k (1 <= k <= 32),执行下面的语句。 (0 <= A, B, C < 2^k)

    long long cnt = 0;
    for (variable = A; variable != B; variable += C)
        cnt++;```
    
    求循环结束后的cnt为多少,如果是死循环,就输出"FOREVER"。其中0 <= variable < 2^k如果variable>=2^k、variable就需要取variable mod 2^k的余数。
    
    **Sample Input**
    > 3 3 2 16
    3 7 2 16
    7 3 2 16
    3 4 2 16
    0 0 0 0
    
    **Sample Output**
    > 0
    2
    32766
    FOREVER
    
    思路:根据循环语句可以得到A + Cx  = B mod 2^k; 即Cx = (B - A) mod 2^k;
    可以联想到逆元,x是C关于2^k的乘法逆元,所以可以转化公式为:Cx + (2^k)y = B - A,而a*x + b*y = c 有解的充要条件是c % gcd(a , b) == 0,此题也就迎刃而解了。
    
    

    include <iostream>

    using namespace std;

    typedef long long ll;

    ll extgcd(ll a, ll b, ll &x, ll &y) {
    int d = a;
    if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= a / b * x;
    }
    else {
    x = 1;
    y = 0;
    }
    return d;
    }

    int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    ll A, B, C, k;
    while (cin >> A >> B >> C >> k && A + B + C + k) {
    k = (ll)1 << k;//注意强制转换
    ll x, y;
    ll a = C;
    ll b = k;
    ll c = B - A;
    ll gcd = extgcd(a, b, x, y);
    if (c % gcd != 0) cout << "FOREVER" << endl;
    else {
    x *= c / gcd;
    ll ans = (x % (b / gcd) + (b / gcd)) % (b / gcd);
    cout << ans << endl;
    }
    }
    return 0;
    }

    相关文章

      网友评论

        本文标题:poj2115(extend gcd + 逆元)

        本文链接:https://www.haomeiwen.com/subject/ghykuttx.html