扩展欧几里得
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;
}
}
}
基础数论 文章被收录于专栏
基础数论学习
OPPO公司福利 1103人发布