2020暑假牛客多校第三场F.Fraction Construction Problem(扩展欧几里得+因式分解)

题目链接

题意:

 

 思路:对原式化简得(c*f-d*e) / (d*f) = a/b。将a/b进行最简式化简得a1/b1

由此可知 c*f-d*e=a1  d*f=b1

分情况考虑,如果b1!=b 则可以令d=b1 f=1 c=a1+b1 e=1。

反之,因为b=c*f,要求c*f-d*e=a1,这很明显是个不定式,所以要令gcd(c,f)=1.所以要找出b的两个互质因子,如果没有则为-1 -1 -1 -1。

找到后用扩展欧几里得求解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int fun(int a,int b)
{
    while(b)
    {
        int c=a%b;
        a=b;
        b=c;
    }
    return a;
}
void exgcd(ll a, ll b, ll& x, ll& y) {
  if (b == 0) {
    x = 1, y = 0;
    return;
  }
  exgcd(b, a % b, y, x);
  y -= a / b * x;
}
void pr(ll c, ll d, ll e, ll f) {
    ll d1 = __gcd(c, d), d2 = __gcd(e, f);
    printf("%lld %lld %lld %lld\n", c/d1, d/d1, e/d2, f/d2);
}
pair<int,int> v[2000010];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        int m=fun(a,b);
        if(m>1)
        {
            int d=b/m;
            int x=a/m;
            int c=x+1,e=1;
            cout<<c<<" "<<d<<" "<<e<<" "<<d<<endl;
            continue;
        }
        else
        {
            ll a1=1,a2=1,flag=0,tot=0;
            int bb=b;
             for(int i = 2; i*i <= bb; ++i) {
            if(bb % i == 0) {
                int c = 0;
                while(bb % i == 0) bb /= i, ++c;
                v[++tot] = make_pair(i, c);
            }
                }
            if(bb > 1) v[++tot] = make_pair(bb, 1);
            if(tot<=1)
            {
                flag=0;
            }
            else
            {
                flag=1;
                for(int i=1;i<=v[1].second;i++) a1*=v[1].first;
                a2=b/a1;
            }
            if(flag==0)
            {
                printf("-1 -1 -1 -1\n");
            }
            else
            {
                ll x,y;
                exgcd(a2,a1,x,y);
                if(y > 0) {
                ll tmp = (y+a2-1)/a2;
                y -= tmp*a2, x += tmp*a1;
                }
                if(x < 0) {
                ll tmp = (-x+a1-1)/a1;
                y -= tmp*a2, x += tmp*a1;
                }
                x*=a;
                y*=a;
                if(x > 0 && y < 0) pr(x, a1, -y, a2);
                else puts("-1 -1 -1 -1");
            }
        }
    }
}

 

posted @ 2020-10-09 15:56  Ldler  Views(62)  Comments(0Edit  收藏  举报