【LuoguP5328】[ZJOI2019]浙江省选

题目链接

题意

给你一堆斜率和纵截距都为正的直线 ,求对于一个条直线是否存在一个 x 使得在这条直线在 x 处能是前 m 大,输出最高能够达到的排名(排名定义为在 x 处严格大于自己的直线条数+1) ,如果不能输出 -1。

\(n\leq 10^5 , m\leq 20\)

Sol

一道思路不算太难但写起来很烦人的题。

对于 \(m=1\) ,我们发现这个就是 [HNOI2008]水平可见直线 那一题 ,唯一要注意的是直线露出的部分上必须有 x 为整数的点。

发现 \(m\) 很小,考虑从小往大处理。
一个比较直观的想法就是把可能排第一的直线全部删掉重新做一次半平面交。
然后我们取出再次能排在第一位的直线,发现这个时候直线合法就相当于是之前被删掉的直线中在当前这条直线露出部分上面的条数不超过 \(k-1\) 条 (k为当前处理的答案)

因为我们只需要做 \(m\) 次半平面交,所以我们即使每次用 \(O(n)\) 的复杂度判断也没事。
于是直接暴力地拿出之前所有被删掉的直线,算出与当前半平面的最左和最右的交点,显然中间的直线都被覆盖一次,差分一下就行了。
看上去很简单,但是细节如 : 精度问题(写个带分数避免),直线上必须有x坐标为整数的点 等等蛇皮问题让人写起来很不爽。

于是代码就不放了。( 因为是抄别人的。)

转载于:https://www.cnblogs.com/NeosKnight/p/11053773.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值