扩展欧几里得

P5656 【模板】二元一次不定方程 (exgcd)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 1e5 + 7;
const ll maxn = 1e5 + 7, maxm = 2e5 + 7;
inline ll read()
{
    ll s = 0, w = 1;
    char ch = getchar();
    while (ch < 48 || ch > 57)
    {
        if (ch == '-')
            w = -1;
        ch = getchar();
    }
    while (ch >= 48 && ch <= 57)
        s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
inline void write(ll m)
{
    if (!m)
    {
        putchar('0');
        return;
    }
    char F[200];
    ll tmp = m > 0 ? m : -m;
    if (m < 0)
        putchar('-');
    int cnt = 0;
    while (tmp > 0)
    {
        F[cnt++] = tmp % 10 + '0';
        tmp /= 10;
    }
    while (cnt > 0)
        putchar(F[--cnt]);
}
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }
ll exgcd(ll a, ll b, ll& x, ll& y)
{
    if(b == 0)
    {
        x = 1, y = 0;
        return a;
    }
    ll d = exgcd(b, a % b, x, y);
    ll z = x; x = y; y = z - y * (a / b);
    return d;
}
int main()
{
    ll t = read();
    while(t--){
        ll  a = read() , b = read(), c = read();
        ll x,y;
        ll d = exgcd(a,b,x,y);//求 ax + by = d 的特解x,y
        if(c % d){
            cout<<"-1"<<endl;
            continue;
        }
        ll m1 = b / d , m2 = a / d;
        x = c / d * x, y = c / d * y;//x,y是方程的特解
        ll minx,miny,maxx,maxy;
        /*if(x > 0 && x % m1 != 0)//cx/d+km1 是通解 
             minx = x % m1;
        else minx = x%m1 + m1;
        if(y > 0 && y % m2 != 0)//cy/d - km2是通解
            miny = y % m2;
        else miny = y%m2 +m2;*/
        minx = (x % m1 + m1) % m1;
        miny = (y % m2 + m2) % m2;
        if(!minx) minx += m1;
        if(!miny) miny += m2;
        maxy = (c - a * minx) / b;
        maxx = (c - b * miny) / a;//最大正整数解是当另一个最小时
        ll cnt = 0;
        if(maxx <= 0){
            cout<<minx<<" "<<miny<<" "<<endl;
        }
        else {
            cnt  =  (maxx - minx ) / m1 + 1;
            cout<<cnt<<" "<<minx<<" "<<miny<<" "<<maxx<<" "<<maxy<<endl;
        }
    }
}
基础数论 文章被收录于专栏

基础数论学习

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务