题目地址【IN】
这个题目可谓非常神啊,博主做了好久,QAQ
题意简述
给你一个数的范围n,和分数qp,保证p,q互质且小于等于n,请求出最大的y1x1<qp,1≤x1,y1≤n和最小的y2x2>qp,1≤x2,y2≤n
数据范围:所有数字都在long long范围内。
我们观察原式y1x1<qp,我们可以发现y1+kqx1+kp<qp是仍然成立的,因为原式变形后得到x1q<y1p,而现在得到x1q+kpq<y1p+kpq,是一样的,所以不变。
由于都是整数,所以y1p−x1q≥1,所以要取极值,就是y1p−x1q=1,又因gcd(p,q)=1,gcd(p,q)∣1的,所以一定有整数解,那么我们用exgcd求出一组x1,y1的解。
然后我们发现y1x1<y1+kqx1+kp的:
证明:
通过相减我们可以得到:
y1x1−y1+kqx1+kp=y1(y1+kq)x1y1+kx1q−x1y1−ky1p=y1(y1+kq)k(x1q−y1p)
由y1x1<qp可知x1q<y1p的,所以最后y1(y1+kq)k(x1q−y1p)为负数,所以y1x1<y1+kqx1+kp,那么我们要求最大的,就是在n的限制内加最多的kp和kq。
对于另一个式子y2x2>qp,我们同理可得y2−kqx2−kp>qp,然后又可以得到y2−kqx2−kp<y2x2的,所以我们求出一组x2,y2然后尽量在n的范围内减去即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int M=1e5+10;
int T;
ll n,p,q;
ll P;
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){x=1;y=0;return a;}
ll t=exgcd(b,a%b,y,x);
y-=x*(a/b);return t;
}
int main(){
for(scanf("%d",&T);T--;){
scanf("%lld%lld%lld",&n,&p,&q);
ll x,y,t1,t2,inv_x,inv_y;
exgcd(p,-q,x,y);
inv_x=-x;inv_y=-y;
t1=min((n-x)/q,(n-y)/p);
t2=min((n+x)/q,(n+y)/p);
x+=t1*q;y+=t1*p;
inv_x+=t2*q;inv_y+=t2*p;
if(x*inv_y<y*inv_x)swap(x,inv_x),swap(y,inv_y);
if(y!=0)printf("%lld %lld
",y,x);
else puts("Yuri is master");
if(inv_x!=0)printf("%lld %lld
",inv_y,inv_x);
else puts("Yuri is master");
}
return 0;
}