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); } }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具