牛客网比赛226C-数学题-题解

题目地址【IN

这个题目可谓非常神啊,博主做了好久,QAQ

题意简述

给你一个数的范围nn,和分数pqfrac{p}{q},保证p,qp,q互质且小于等于nn,请求出最大的x1y1<pq,1x1,y1nfrac{x_1}{y_1}<frac{p}{q},1leq x_1,y_1leq n和最小的x2y2>pq,1x2,y2nfrac{x_2}{y_2}>frac{p}{q},1leq x_2,y_2leq n

数据范围:所有数字都在long longlong long范围内。


我们观察原式x1y1<pqfrac{x_1}{y_1}<frac{p}{q},我们可以发现x1+kpy1+kq<pqfrac{x_1+kp}{y_1+kq}<frac{p}{q}是仍然成立的,因为原式变形后得到x1q<y1px_1q<y_1p,而现在得到x1q+kpq<y1p+kpqx_1q+kpq<y_1p+kpq,是一样的,所以不变。

由于都是整数,所以y1px1q1y_1p-x_1qgeq 1,所以要取极值,就是y1px1q=1y_1p-x_1q=1,又因gcd(p,q)=1gcd(p,q)=1gcd(p,q)1gcd(p,q)|1的,所以一定有整数解,那么我们用exgcd m exgcd求出一组x1,y1x_1,y_1的解。

然后我们发现x1y1<x1+kpy1+kqfrac{x_1}{y_1}<frac{x_1+kp}{y_1+kq}的:

证明:

通过相减我们可以得到:

x1y1x1+kpy1+kq=x1y1+kx1qx1y1ky1py1(y1+kq)=k(x1qy1p)y1(y1+kq)frac{x_1}{y_1}-frac{x_1+kp}{y_1+kq}=frac{x_1y_1+kx_1q-x_1y_1-ky_1p}{y_1(y_1+kq)}=frac{k(x_1q-y_1p)}{y_1(y_1+kq)}

x1y1<pqfrac{x_1}{y_1}<frac{p}{q}可知x1q<y1px_1q<y_1p的,所以最后k(x1qy1p)y1(y1+kq)frac{k(x_1q-y_1p)}{y_1(y_1+kq)}为负数,所以x1y1<x1+kpy1+kqfrac{x_1}{y_1}<frac{x_1+kp}{y_1+kq},那么我们要求最大的,就是在nn的限制内加最多的kpkpkqkq


对于另一个式子x2y2>pqfrac{x_2}{y_2}>frac{p}{q},我们同理可得x2kpy2kq>pqfrac{x_2-kp}{y_2-kq}>frac{p}{q},然后又可以得到x2kpy2kq<x2y2frac{x_2-kp}{y_2-kq}<frac{x_2}{y_2}的,所以我们求出一组x2,y2x_2,y_2然后尽量在nn的范围内减去即可。

#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);
//		if(p==n||(p==1&&q==n)){puts("Yuri is master");continue;}
		ll x,y,t1,t2,inv_x,inv_y;
		exgcd(p,-q,x,y);//求最小x,y满足条件(这里好像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;
}


原文地址:https://www.cnblogs.com/VictoryCzt/p/10053389.html