二分、单项指针与小数换分数

核心:判断的时候利用单调性、小数取近似值置换分数。

#include<bits/stdc++.h>
using namespace std;
int n,q;
long double a[1000010],b[1000100];
bool p[1000010];
bool cmp(int a,int b){
	return a>b;
}
void print(int a,int b){
	cout<<a/__gcd(a,b)<<" "<<b/__gcd(a,b)<<endl;
}
long long rnk(long double c){
	int j = 0;
	long long ans = 0;
	for(int i = 1;i <= n;i++){
		while(j+1<=n&&(long double)a[j+1]<=c*b[i])j++;
		//cout<<j<<endl;
		ans+=j;
	}
	return ans;
}
signed main(){
	cin>>n>>q;
	for(int i = 1;i <= n;i++){
		cin>>a[i];
		p[int (a[i] )] =1;
	}
	for(int i = 1;i <= n;i++){
		cin>>b[i];
	}
	sort(a+1,a+1+n);
	sort(b+1,b+1+n);
	while(q--){
		long long x;
		cin>>x;
		long double L = a[1]/b[n],R = a[n]/b[1];
		while(R-L >= 1e-13){
			long double mid = (L+R)/2;
			//cout<<mid<<" "<<rnk(mid)<<endl;
			if(rnk(mid) >= x){
				R = mid;
			}
			else{
				L = mid;
			}
		}
	//	cout<<L<<endl;
		for(int i = 1;i <= n;i++){
			int A = round(L*b[i]);
		//	cout<<"AAA"<<A<<" "<<double(b[i]*L-A)<<endl;
			if(p[A]&&A <= 1e6&&abs(double(A-b[i]*L))<= 1e-7){
				print(A,b[i]);
				break;
			}
		}
	}
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值