The third F-Fractio Construction Problem (Expanded Euclid)

The title is marked here
:
Insert picture description here
under discussion:
1. Set g = gcd (a, b), if g> 1, it is not the simplest fraction. In this case, let d = b/g, c = a+ b,e = f = 1, just because the structure is
2.g = 1, which satisfies d <b and f <b . At this time, the fraction is the simplest fraction, but if b cannot be decomposed into two different Prime factor, the construction cannot be completed at this time, directly output -1
3.g = 1, but at this time b has two different prime factors, and the numerator can become cf-de = a gcd(f,d ), even if the equation fx-dy = a gcd(f, d) is not solved , it can be known that it becomes an extended Euclidean problem.
Finally, don’t forget that we find the result and multiply it by a, which corresponds to our problem.

Code:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 2e6+7;
int prime[MAXN],fac[MAXN],cnt;

ll gcd(ll a,ll b){
    
    
	if(a < b) swap(a,b);
	ll r;
	while(a%b != 0){
    
    
		r = a % b;
		a = b;
		b = r;
	}
	return b;
}

ll exgcd(ll a,ll b,ll &x,ll &y){
    
    
	if(!b){
    
    
		x = 1, y = 0;
		return a;
	}
	ll g = exgcd(b,a%b,y,x);
	y -= (a/b)*x;
	return g;
}

void euler(){
    
    //欧拉筛打出当前的数的质因数是多少
	int t;
	fac[1] = 1;
	for(int i = 2;i < MAXN;i ++){
    
    
		if(!fac[i]){
    
    
			prime[++cnt] = i;
			fac[i] = i;
		}
		for(int j = 1;(t = i*prime[j]) < MAXN;j ++){
    
    
			fac[t] = prime[j];
			if(i % prime[j] == 0) break;
		}
	}
}

int main()
{
    
    
	ll a,b,c,d,e,f;
	int t;
	euler();
	scanf("%d",&t);
	while(t--){
    
    
		scanf("%lld%lld",&a,&b);
		ll g = gcd(a,b);
		if(g > 1){
    
    
			a /= g,b /= g;
			d = b,c = b + a,e = f = 1ll;
			printf("%lld %lld %lld %lld\n",c,d,e,f);
		}
		else{
    
    
			d = 1,f = b;
			while(fac[b] != 1 && f%fac[b] == 0){
    
    //有多个质因子的情况
				d *= fac[b];
				f /= fac[b];
			}
			if(b == d || f == 1){
    
    //不能进行分解的情况
				puts("-1 -1 -1 -1");
			}
			else{
    
    
				exgcd(f,d,c,e);
				e = -e;
				while(e <= 0 ||c <= 0){
    
    
					e += f;
					c += d;
				}
				e *= a;
				c *= a;
				printf("%lld %lld %lld %lld\n",c,d,e,f);
			}
		}
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45672411/article/details/107691208