链接:戳这里
思路:
裸地扩展欧几里得算法 我的一些推导过程在代码中给出
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; ll gcd(ll a,ll b){ return b==0 ? a : gcd(b,a%b); } /* 满足|x| + |y| 最小 使得 ax+by=d d=gcd(a,b) ax1+by1=gcd(a,b); bx2+(a%b)y2=gcd(b,a%b); => ax1+by1=bx2+(a%b)y2 ax1+by1=bx2+(a-a/b*b)y2 ax1+by1=bx2+ay2-b*(a/b)y2 ax1+by1=ay2+b(x2-(a/b)y2) => x1=y2 y1=x2-(a/b)*y2 */ void exgcd(ll a,ll b,ll &d,ll &x,ll &y){ if(!b) {d=a;x=1;y=0;} else { exgcd(b,a%b,d,x,y); ll x1=y; ll y1=x-(a/b)*y; x=x1;y=y1; /* exgcd(b,a%b,d,y,x); y=y-x*(a/b); */ } } int main(){ ll a,b; while(scanf("%I64d%I64d",&a,&b)!=EOF){ if(gcd(a,b)!=1) printf("sorry\n"); else { ll d=1,x,y; exgcd(a,b,d,x,y); while(x<=0){ x+=b; y-=a; } /* ax+by=1 (x<0) a(x+1)=1-by+a ax'=1-b(y-a/b) x'=x+1 y'=y-a/b =>x+ 1 <==>y+ -a/b x+ b <==>y+ -a */ printf("%I64d %I64d\n",x,y); } } return 0; }