F.Fraction Construction Problem(exgcd&数论)
题意:给定正整数 ,构造出正整数 ,满足
思路: 数论。
不互质时,即 。
我们可以构造这样一个式子:
令 。
即 。
这样能满足 。
互质且 质因数的种类只有一个。
这种情况是无解的,因为 ,所以 的分解质因数 的个数都小于 的 个数,所以左边 通分后,分母不可能等于 。
互质且 质因数种类不只一个。
显然我们可以构造出互质的两个数 满足 。
这样有 。
即 ,在 已知下求 ,这显然是扩展欧几里得。
且肯定有整数解,因为 互质,说明 则必定有整数解。
接下来套板子就可以了 ,注意是求正整数解,所以当 为负数时要将其变为正整数。
可能有人会问 为正数时,能不能保证 也是正数呢,当然可以。
因为 ,显然 为正数,因为 为正数,显然 为正数。
即: 都为正数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int a,b,p[N],vis[N],ss[N];
void pre(){
int n=2e6,cnt=0;
ss[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i])
p[cnt++]=i,ss[i]=i;
for(int j=0;j<cnt&&i*p[j]<=n;j++){
vis[i*p[j]]=1,ss[i*p[j]]=p[j];
if(i%p[j]==0) break;
}
}
}
template<class T>
void exgcd(T a,T b,T &x,T &y){
if(!b){
x=1,y=0;
return;
}
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}
int main(){
int t;
pre();
scanf("%d",&t);
while(t--){
scanf("%d%d",&a,&b);
int g=__gcd(a,b);
if(g>1){
printf("%d %d 1 1\n",(a+b)/g,b/g); //不互质.
continue;
}
ll f=b,d=1;
while(b>1&&f%ss[b]==0) f/=ss[b],d*=ss[b];
if(f==b||f==1) puts("-1 -1 -1 -1");
else {
ll c,e;
exgcd(f,d,c,e);
if(c<0)
c=(c%d+d)%d,e=(1-f*c)/d;
c*=a,e*=a;
printf("%lld %lld %lld %lld\n",c,d,-e,f);
}
}
return 0;
}