P6733 题解

P6733 「Wdsr-2」间歇泉 题解

算法分析

由于 \(k\) 达到了 \(10^{10}\) 的级别,所以正常暴力做法肯定不行,于是考虑二分。

二分 \(mid\)

注意:实数二分要考虑精度。

check 函数公式推导

\[\sum_{i=1}^{n}\sum_{j=1}^{n} [mid \le \frac{a_ic_i+a_jc_j}{a_i+a_j}] \ge k \]

时返回 true,反之返回 false。

展开,得

\[\sum_{i=1}^{n}\sum_{j=1}^{n} [a_imid+a_jmid \le a_ic_i+a_jc_j] \ge k \]

移项,得

\[\sum_{i=1}^{n}\sum_{j=1}^{n} [a_ic_i+a_imid \le a_jc_j+a_jmid] \ge k \]

此时,\(a_ic_i+a_imid\)\(a_jc_j+a_jmid\) 都可以以 \(O(n)\) 的代价预处理出来。

排序后用双指针求出
\(\sum_{i=1}^{n}\sum_{j=1}^{n} [a_imid+a_jmid \le a_ic_i+a_jc_j]\) 的量。

此时,\((i,j)\)\((j,i)\) 都算了一遍。所以,我们再将这个答案除以 \(2\)

注意:自己与自己不能混和,当 \([a_imid+a_jmid = a_ic_i+a_jc_j]\) 时答案减一。

复杂度

编程语言:C++98 O2;

代码长度:752B;

用时:1.04s;

内存:3.36MB。

理论复杂度 \(O(n \log^2 n)\)

CODE

#include<bits/stdc++.h>
#define int long long
const int N=1e5+5;
const double eps=1e-4;
int n,k;
double a[N],c[N]; 
double x[N],y[N]; 
bool check(double mid){
	int res=0;
	for(int i=1;i<=n;i++){
		x[i]=a[i]*c[i]-a[i]*mid;
		y[i]=a[i]*mid-a[i]*c[i];
		if(y[i]-x[i]<eps)	res--;
	}
	std::sort(x+1,x+n+1);
	std::sort(y+1,y+n+1);
	int j=0;
	for(int i=1;i<=n;i++){
		while(y[j+1]-x[i]<eps&&j<n)j++;
		res+=j;
	}
	return res/2>=k;
}
signed main(){
	std::ios::sync_with_stdio(0);
	std::cin.tie(0),std::cout.tie(0);
	std::cin>>n>>k;
	for(int i=1;i<=n;i++)
		std::cin>>a[i]>>c[i];
	double l=1,r=1e9;
	for(int i=1;i<=50;i++){
		double mid=(l+r)/2.0;
		if(check(mid))	l=mid;
		else	r=mid;
	}
	printf("%.3f\n",l);
	return 0;
}

完结撒花

posted @ 2026-01-29 21:31  concert_b  阅读(0)  评论(0)    收藏  举报