Codeforces - 773A - Success Rate - 二分 - 简单数论
https://codeforces.com/problemset/problem/773/A
一开始二分枚举d,使得(x+d)/(y+d)>=p/q&&x/(y+d)<=p/q,错在这些数是离散的,不能由两边异号判定一定存在这个交点。
然后改成枚举d,使得y=d*q,这样就一定是倍数了。然后就是要想清楚了,找不到这样卡在中间的d,其实都是因为d不够大的原因,d够大保证是可以的除非正确率是100%。
然后就是二分的上界,按道理q的最大值是1e9,y的最大值也是1e9,他们的公倍数肯定在1e18范围内(p和q任意组合能得到的比值最多就是1e18/2,把1e18都枚举完肯定能遍历所有能构造出的情况),那么最大值肯定是1e18/q,多个1都不行。
二分,老朋友了,while(1),当l==m的时候是边界,特判就好。
#include<bits/stdc++.h> using namespace std; #define ll long long string a,b; string c; int main(){ int t; scanf("%d",&t); while(t--){ ll x,y,p,q; scanf("%lld%lld%lld%lld",&x,&y,&p,&q); ll l=1,r=1e18/q,m; ll ans; while(1){ m=(l+r)>>1; //cout<<l<<" " <<r<<" "<<m<<endl; if(l==m){ ll del=l*q-y; if(del>=0&&(x+del)>=l*p&&x<=l*p){ ans=l; } else if((r*q-y)>=0&&(x+(r*q-y))>=r*p&&x<=r*p){ ans=r; } else{ ans=-1; } break; } if(m*q<y){ l=m+1; continue; } ll del=m*q-y; if((x+del)>=m*p&&x<=m*p){ r=m; //cout<<m<<" ok"<<endl; } else{ l=m+1; } } printf("%lld\n",ans==-1?-1:ans*q-y); } }
其实还有直接用公式解的方法,设最终的状态为pt/qt,只要保证增量为正数即可,当然是pt>=x,qt>=y,还有错的题不会再变对,qt-pt>=y-x,三个式子直接解出来。
这个方法要注意特判p==q的情况,这种时候不能作除法,还有p==0和q==0的时候。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
· 用 DeepSeek 给对象做个网站,她一定感动坏了
· .NET 8.0 + Linux 香橙派,实现高效的 IoT 数据采集与控制解决方案
· DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件