[BJWC2018]第k大斜率

题目链接:[BJWC2018]第k大斜率


显然可以二分答案,然后找大于当前答案的斜率个数。

怎么判断呢?

假设当前斜率为k,则:(yi-yj) / (xi-xj) > k
假设xi>xj 则:
yi-k*xi>yj-k*xj
只要满足这个条件即可,其实我们可以发现,就是一个二维偏序。

AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,k,res,d[N],l=-2e8,r=2e8;
struct node{int x,y;}t[N];
vector<int> v;
int cmp(node a,node b){return a.x==b.x?a.y>b.y:a.x<b.x;}
inline void insert(int x){for(;x<=v.size();x+=x&(-x)) d[x]++;}
inline int ask(int x){int s=0; for(;x;x-=x&(-x)) s+=d[x]; return s;}
inline int sum(int l,int r){return ask(r)-ask(l-1);}
inline int check(int mid){
	v.clear();	res=0;	memset(d,0,sizeof d);
	for(int i=1;i<=n;i++)	v.push_back(t[i].y-mid*t[i].x);
	sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
	for(int i=1,val;i<=n;i++){
		val=lower_bound(v.begin(),v.end(),t[i].y-mid*t[i].x)-v.begin()+1;
		res+=ask(val),insert(val);
	}
	return res>=k;
}
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)	scanf("%lld %lld",&t[i].x,&t[i].y);
	sort(t+1,t+1+n,cmp);
	while(l<r){
		int mid=l+r+1>>1;
		if(check(mid))	l=mid;
		else	r=mid-1;
	}
	printf("%lld\n",l);
	return 0;
}
发布了725 篇原创文章 · 获赞 244 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104704760
今日推荐