如果 j 在原本选择的 F 中,从 F 中去掉 j,再选择其它线段中 \max(a_i,b_i) 最小的线段加入 F。
否则直接计算。
随后便可以计算 f,最后取最大答案输出即可。
AC Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define F first
#define S second
int n,pre[100005],sum,d[100005];
pair<int,int> p[100005];
signed main(){
// freopen("big.in","r",stdin);
// freopen("big.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++) cin>>p[i].F>>p[i].S,sum+=max(p[i].S-p[i].F,0ll);
sort(p+1,p+n+1,[](pair<int,int> a,pair<int,int> b){return max(a.F,a.S)<max(b.F,b.S);});//按照max(a[i],b[i])排序
for(int i=1;i<=n;i++){
pre[i]=pre[i-1]+max(p[i].F,p[i].S);
d[i]=max(p[i].F-p[i].S,0ll);
}
int pos=upper_bound(pre+1,pre+1+n,sum)-pre-1;//计算最大的|F|
int ans1=0,ans2=1;
for(int i=1;i<=n;i++){
int summ=sum-d[i];
if(i<=pos) summ=summ-pre[pos+1]+max(p[i].F,p[i].S);
else summ=summ-pre[pos];
if(summ>p[i].S) summ=p[i].S;
if(summ>0){
if((__int128)ans1*p[i].S<(__int128)ans2*summ){//取最大的f
ans1=summ;
ans2=p[i].S;
}
}
}
ans1+=pos*ans2;//加|F|
ans2*=n;//分母原本为n
int gcd=__gcd(ans1,ans2);//约分
cout<<ans1/gcd<<' '<<ans2/gcd;
return 0;
}