F Fraction Construction Problem

题意:

给两个数a,b求另外四个数c,d,e,f满足

  1. c d − e f = a b \frac{c}{d} - \frac{e}{f} = \frac{a}{b} dcfe=ba
  2. d < b and f < b
  3. 1 ≤ c , e ≤ 4 × 1 0 12 1≤c,e≤4×10^{12} 1c,e4×1012
    如果不存在就输出-1 -1 -1 -1

思路:

看了题解之后来写一下思路,当时做一个笔记。

这题的关键点在于第二个条件,如果没有第二个条件,这就是一道非常简单的水题因为直接构造 a + k b − k b \frac{a + k}{b} - \frac{k}{b} ba+kbk(这不是乱杀么 )。

但是有了条件二就无法这样构造,条件二似乎在提示我们, d ∗ f d * f df一定要是 b b b的整数倍,而且 d d d f f f每个都一定要含有 b b b的非1因子,否则无法满足条件二。

那么很自然就会想到质数,当 b b b为质数时上述条件似乎就无法满足了,但是如果分子是质数倍数的话不就又可以直接构造了么?

  1. 此时就可以自然地想到,假设分子分母不互质,那么毕竟约分后分母小于原分母,那么约分后的分数就可以随便构造了
    比如:
    约分后是 u n \frac{u}{n} nu那么就可以构造 u + 1 n − 1 n \frac{u + 1}{n} - \frac{1}{n} nu+1n1(真就乱杀呗 )
  2. 那么当分子和分母互质时呢,此时把式子进行通分得 c f − e d d f = a b \frac{cf -ed}{df} = \frac{a}{b} dfcfed=ba,根据上面的条件 d d d f f f每个都一定要含有 b b b的非1因子,若 d d d f f f不互质,那么 c f − e d d f = a b \frac{cf -ed}{df} = \frac{a}{b} dfcfed=ba就会约分,那么 d f df df一定到达不了 b b b,所以对于存在的质因子数等于1的b一定无解
  3. d d d f f f互质时 d ∗ f = b d*f = b df=b所以只需要求出 c c c e e e满足 c f − e d = a cf-ed=a cfed=a这明显就是exgcd的内容了
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define pb push_back
#define eps 1e-8
#define endl '\n'
using namespace std;
const ll maxn = 2e6 + 5;

ll t,a,b,c,d,e,f,cb[maxn];
bool vis[maxn];

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

void Sz(){
    for(int i = 2; i <= maxn; i++){
        if(!vis[i]){
            vis[i] = 1;
            for(int j = i + i; j <= maxn; j += i){
                vis[j] = 1;
                if(!cb[j]){
                    ll k = i;
                    while(!(j % (k * i))) k *= i;
                    if(k < j)cb[j] = k;
                }
            }
        }
    }
}

void solve(){
    ll x,y,d = __gcd(a,b);
    if(d != 1)
        printf("%lld %lld %lld %lld\n",a / d + 1,b / d,1ll,b / d);
    else{
        if(!cb[b])printf("-1 -1 -1 -1\n");
        else{
            d = cb[b],f = b / d;
            exgcd(d,f,x,y);
            if(x > 0)
                printf("%lld %lld %lld %lld\n",x * a,f,-y * a,d);
            else
                printf("%lld %lld %lld %lld\n",y * a,d,-x * a,f);
        }
    }
}

int main(){
    Sz();
    scanf("%lld",&t);
    while(t--){
        scanf("%lld %lld",&a,&b);
        solve();
    }
    return 0;
}


 
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页