P5656 【模板】二元一次不定方程(exgcd)
阿新 • • 發佈:2020-08-04
還不會 exgcd 的請移步窩的學習筆記,這裡只講怎麼搞出煩人的答案。
在 \(a,b\) 兩者互質的情況下,二元一次不定方程的通解:\(a(x+db)+b(y+da)=c\)。
判定是否有解不多說,考慮有正整數解怎麼判。
對於未知數 \(x,y\),在其中一個滿足條件的同時我們希望另一個儘可能大。仔細觀察資料範圍,發現 \(a,b,c\) 均為正整數,也就是說隨著 \(x\) 的增大 \(y\) 會減小,那我們將一個取最小正整數解另一個算一下是否大於 \(0\) 即可。
然後很容易看出一個的最小正整數解就是另一個的最大正整數解。
記得開 long long
,解記得乘上 \(c/\gcd(a,b)\)
時間複雜度 \(O(T\log a)\)~
code:
#include<bits/stdc++.h> using namespace std; #define int long long int x,y; int read() { int A; bool K; char C; C=A=K=0; while(C<'0'||C>'9')K|=C=='-',C=getchar(); while(C>'/'&&C<':')A=(A<<3)+(A<<1)+(C^48),C=getchar(); return(K?-A:A); } void exgcd(int a,int b) { if(!a) { x=0; y=1; return; } int tmp; exgcd(b%a,a); tmp=y; y=x; x=tmp-b/a*x; } int gcd(int _,int __) { return(!_?__:gcd(__%_,_)); } void write(int X) { if(X<0)putchar('-'),X=-X; if(X>9)write(X/10); putchar(X%10|48); } signed main() { int t,a,b,c,k; t=read(); while(t--) { a=read(),b=read(),c=read(); k=gcd(a,b); if(c%k) { puts("-1"); continue; } exgcd(a,b); c/=k; x*=c; y*=c; a/=k; b/=k; x=(!((x%b+b)%b)?b:(x%b+b)%b); y=(c-x*a)/b; if(y>0) { write((y-1)/a+1); putchar(' '); write(x); putchar(' '); y=(!(y%a)?a:y%a); write(y); putchar(' '); x=(c-y*b)/a; write(x); putchar(' '); write((c-(!(x%b)?b:x%b)*a)/b); } else { write(x); putchar(' '); write((!((y%a+a)%a)?a:(y%a+a)%a)); } putchar('\n'); } return 0; }