lam_dyr
2025-01-10 10:17:50
人生第一道紫题题解 qaq
给定平面上
由于
二分斜率:
那么如何计算斜率
由点斜式方程
得
注意
此时不妨将所有点按
对所有计算得到的
注意一点:当
#include <iostream>
#include <algorithm>
#define int long long
#define lowbit(x) x & (-x)
using namespace std;
typedef long long ll;
int sz;
int tr[200005],tx[100010],ty[100010];
int x[100005],y[100005],idx[100005];
void upd(int x,int y=1) {
while(x<=sz){
tr[x]+=y;
x+=lowbit(x);
}
}
int qry(int x) {
int res=0;
while(x>0){
res+=tr[x];
x-=lowbit(x);
}
return res;
}
ll cnt_ge(int m,int tx[],int ty[],int n){
ll c[100010];
for(int j=0;j<n;j++)
c[j]=(ll)ty[j]-(ll)m*tx[j];
ll srt[100010];
for(int i=0;i<n;i++) srt[i]=c[i];
sort(srt,srt+n);
int unisz=unique(srt,srt+n)-srt;
int rnk[100010];
for(int j=0;j<n;j++)
rnk[j]=lower_bound(srt,srt+unisz,c[j])-srt+1;
sz=unisz;
fill(tr,tr+sz+1,0);
ll tot=0;
int j=0;
while(j<n){
int cur=tx[j];
int l=j;
while(j<n && tx[j]==cur)
j++;
int r=j;
for(int t=l;t<r;t++)
tot+=qry(rnk[t]);
for(int t=l;t<r;t++)
upd(rnk[t]);
}
return tot;
}
bool cmp(int i, int j) {
if(x[i]!=x[j]) return x[i]<x[j];
return y[i]<y[j];
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++) cin>>x[i]>>y[i];
for(int i=0;i<n;i++) idx[i]=i;
sort(idx,idx+n,cmp);
for(int i=0;i<n;i++){
tx[i]=x[idx[i]];
ty[i]=y[idx[i]];
}
int l=-1000000000;
int r=1000000000;
int ans=-1;
while(l<=r){
int mid=l+(r-l)/2;
ll cnt=cnt_ge(mid,tx,ty,n);
if(cnt>=(ll)k){
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
cout<<ans;
return 0;
}
//不开long long见祖宗。