牛客2020多校第三场 F.Fraction Construction Problem

牛客2020多校第三场

F.Fraction Construction Problem

https://ac.nowcoder.com/acm/contest/5668/F

分析:

1.a,b不互质,因为题目要求d<b,f<b,所以只要gcd(a,b)=g!=1,分母就可以直接写成b/g的形式,只要再构造一下式子,如a/g+1,b/g,1,b/g就是一组答案。

2.在b的因数里面找一对d,f互质却d*f=b。找不到则无解,找到了可以通分把式子化成f * c -d * e=a,然后就变成exgcd的形式(c,-e是未知数)。求得c',e'的解后,由exgcd通解c=c' * a +b/gcd(a,b) * k,e=e' * a -a/gcd(a,b) * k,这时可以令k=0,得到答案就是c' * a,e' * a。要注意因为求得的e'一定是负的,c'可能是负的,为保证c'是正数,可以让c'一直+d,e'一直+f。因为在原式中,(c+k * d)/d - (e+k * f)/f=a/b,k任取。

3.证明为什么找不到一对互质且d*f=b就是无解?

  如果d,f不互质,即f=k*d,式子可化为(k * c-e)/f=a/b,因为f<b,且a,b互质,所以a/b已经是最简形式,而f<b,使得左式不可能等于右式。

同理如果d * f != b,设d*f==p则通分后,(c * f - e * d)/p 必定不等于a/b,因为分母不同。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<deque>
#include<cmath>
#include<map>
#include<queue>
#include<bitset>
#define sd(x) scanf("%d",&x)
#define ms(x,y) memset(x,y,sizeof x)
#define fu(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=2e6+79;
const int mod=1e9+7;
const ll INF=1e18+7;
vector<int> cob;
int gcd(int a,int b)
{
    if(a<b) swap(a,b);
    if(b==0) return a;
    return gcd(b,a%b);
}
void depart(int b)
{
    cob.clear();
    for(int i=2;i*i<=b;i++)
    {
        if(b%i==0) 
        {
            if(gcd(i,b/i)==1) 
            {
                cob.push_back(i);
                break;
            }
            //找到一对互质的
        }
    }
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    ll d=a;
    if(b!=0)
    {
        d=exgcd(b,a%b,y,x);
        y-=(a/b)*x;
    }
    else
    {
        x=1,y=0;
    }
    return d;
    
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int a,b,g;
        sd(a);sd(b);
        ll c,d,e,f;
        if((g=gcd(a,b))!=1)
        {
            c=a/g+1,d=b/g,e=1,f=b/g;
        }
        else
        {
            depart(b);
            if(cob.size()>=1)
            {
                d=cob[0],f=b/d;
                exgcd(f,d,c,e);
                e=-e;
                while(c<=0||e<=0) c+=d,e+=f;
                c*=a;
                e*=a;
            }
            else c=d=e=f=-1;
        }
        printf("%lld %lld %lld %lld\n",c,d,e,f);
    }
    return 0;
}

 

posted on 2020-07-26 22:42  Aminers  阅读(116)  评论(0编辑  收藏  举报

导航