【LuoguP5328】[ZJOI2019]浙江省选

题目链接

题意

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

(nleq 10^5 , mleq 20)

Sol

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

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

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

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

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

原文地址:https://www.cnblogs.com/NeosKnight/p/11053773.html