扩展欧几里得 求ax+by == n的非负整数解个数

求解形如ax+by == n (a,b已知)的方程的非负整数解个数时,需要用到扩展欧几里得定理,先求出最小的x的值,然后通过处理剩下的区间长度即可得到答案。

放出模板:

ll gcd(ll a, ll b) {
    return b ? gcd(b, a%b) : a;
}

ll lcm(ll a, ll b) {
    return a / gcd(a,b) * b;
}

ll extend_gcd(ll a,ll b,ll&x,ll&y) {
    if(!b) {
        x = 1;
        y = 0;
        return a;
    }
    ll xt = 0, yt = 0;
    ll d = extend_gcd(b, a % b, xt, yt);
    x = yt;
    y = xt - yt * (a/b);
    return d;
}

ll cal(ll a,ll b,ll n) {    //计算ax+by == n的非负整数解组数
    ll x = 0,y = 0,d;
    d = extend_gcd(a,b,x,y);
    if(n % d != 0) {
        return 0;
    }
    x *= n / d, y *= n / d;
    ll LCM = lcm(a,b);
    ll t1 = LCM / a, t2 = LCM / b;
    if(x<1) {
        ll num = (1-x) / t1;
        x += num * t1;
        y -= num * t2;
        if(x<1) {
            y -= t2;
            x += t1;
        }
    }
    if(y<1) {
        ll num = (1-y) / t2;
        y += num * t2;
        x -= num * t1;
        if(y<1) {
            y += t2;
            x -= t1;
        }
    }
    ll ans = x > 0 && y > 0;
    if(ans) {
        ans += min((x-1) / t1, ((n-1) / b - y) / t2);
        ans += min((y-1) / t2, ((n-1) / a - x) / t1);
    }
    return ans;
}

猜你喜欢

转载自www.cnblogs.com/zinyy/p/9139102.html