2020牛客多校三 F-Fraction Construction Problem (欧几里得+构造)

题目链接:传送门

 

 

 


 

思路:

1.考虑 a b 不互质,即 r=gcd(a,b)>1 ;那么可以构造出 c=(a/r)+1 d=b/r e=1 f=b/r (要求d<b && f<b ,因此 r 必须大于1)

2.考虑 a b 互质,即 r=gcd(a,b)=1; 那么可以得到式子 (cf-ed)/df = a/b ,可以令d*f = b, 那么可以根据b的值构造出d f,然后解不定方程 cf - ed = a ,其中 a d f 是已知系数;

 根据不定方程可知 gcd(d,f) = 1 ,因为a与b互质,那么肯定a与gcd(d,f) 互质 ,a%1=0;  所以必须要构造出互质d f,这样就必须要求b有两个及以上的质因子个数。  

其余情况无解。

 

复制代码
#include<bits/stdc++.h>
/*
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<cctype>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
*/
#pragma GCC optimize(2)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
typedef pair<double,double> pdd;
const int N=2e6+5;
const int M=8e5+5;
const int inf=0x3f3f3f3f;
const LL mod=1e9+7;
const double eps=1e-5;
const long double pi=acos(-1.0L);
#define ls (i<<1)
#define rs (i<<1|1)
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define mk make_pair
#define mem(a,b) memset(a,b,sizeof(a))
LL read()
{
    LL x=0,t=1;
    char ch;
    while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
    while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
    return x*t;
}
int cnt[N],num[N];
int gcd(int x,int y)
{
    return y==0?x:gcd(y,x%y);
}
int exgcd(int a,int b,LL &x,LL &y)
{
    //printf("...\n");
    if(b==0)
    {
        x=1; y=0;
        return a;
    }
    LL x1,y1;
    int t=exgcd(b,a%b,x1,y1);
    x=y1;
    y=x1-a/b*y1;
    return t;
}
void init()
{
    for(int i=2;i*i<N;i++)
    {
        if(num[i]) continue;
        num[i]=i;
        for(int j=i*i;j<N;j+=i)
        {
            if(num[j]) continue;
            num[j]=i;
            cnt[j]++;
            int t=j;
            while(t%i==0) t/=i;
            if(t>1) cnt[j]++;
        }
    }
}
int main()
{
    init();
    //for(int i=25;i<=30;i++) printf("..%d %d\n",num[i],cnt[i]);
    int T=read();
    while(T--)
    {
        int a=read(),b=read();
        int r=gcd(a,b);
        //printf("r = %d\n",r);
        if(r>1)
        {
            printf("%d %d %d %d\n",a/r+1,b/r,1,b/r);
            continue;
        }
        if(cnt[b]<2)
        {
            printf("-1 -1 -1 -1\n");
            continue;
        }
        LL d=1,f=b;
        while(f%num[b]==0) f/=num[b];
        d=b/f;
        LL x,y;
        exgcd(f,d,x,y);
        //printf("%d %d")
        y=-y;
        while(x<=0||y<=0) x+=d,y+=f;//x 是和"b"相关的,这里的b指的就是d;
        printf("%lld %lld %lld %lld\n",x*a,d,y*a,f);
    }
}
View Code
复制代码

 

posted @   DeepJay  阅读(169)  评论(0编辑  收藏  举报
编辑推荐:
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
阅读排行:
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
点击右上角即可分享
微信分享提示