歐幾里得及拓展歐幾里得
阿新 • • 發佈:2018-12-10
歐幾里得
int gcd(int a,int b){
return (b==0)?a:gcd(b,a%b); //一條語句搞定(三元運算子)裝逼,跟上面略有不同,上面做到t=0,這裡做到b=0
}
拓展歐幾里得
int gcd(int a,int b){ return (b==0)?a:gcd(b,a%b); //一條語句搞定(三元運算子)裝逼,跟上面略有不同,上面做到t=0,這裡做到b=0 } ll lcm(ll a, ll b) { return a / gcd(a,b) * b; } int exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return a; } int r=exgcd(b,a%b,x,y); int t=x; x=y; y=t-a/b*y; return r; }
拓展歐幾里得求整數解個數
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; }