一眼看上去就应该能用半平面交去做。

首先考虑怎么求可能得第1名的人:每个人的函数为直线,就是在所有人的半平面交中的上边界者即可获得第一名,这个可以单调队列求解。

再考虑如何求可能得第2名的人:满足2个条件:1、在去掉可能得第1名的人后可以拿第1,这个跳转到上面的过程;2、至多同时被1个能拿第一名的人超越,这个应该在半平面上做一个区间覆盖,可以线段树或者二分求解,我懒得不会写线段树就只写了二分。

第3~m名,可以仿照第2名的过程,做m次半平面交,其实会m=2就是会正解了。

时间复杂度O(nmlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,int>pii;
const int N=1e5+;
struct node{
ll a,b,c;
node(){a=b=,c=;}
node(ll x,ll y){if(y<)x=-x,y=-y;a=x/y;b=x%y;c=y;if(b<)b+=c,a--;}
ll ceil(){return a+(b>);}
bool operator<(const node&t)const{return a==t.a?b*t.c<t.b*c:a<t.a;}
bool operator<=(const node&t)const{return a==t.a?b*t.c<=t.b*c:a<t.a;}
}p[N];
int n,m,top,tot,id[N],ans[N],st[N];
ll a[N],b[N];
pii s[N<<];
bool cmp(int x,int y){return a[x]<a[y]||a[x]==a[y]&&b[x]>b[y];}
node cross(int x,int y){return node(b[y]-b[x],a[x]-a[y]);}
void solve(int k)
{
top=tot=;
p[]=node(,);
for(int i=;i<=n;i++)
if(ans[id[i]]==-&&a[id[i]]>a[st[top]])
{
while(top&&cross(id[i],st[top]).a<p[top].ceil())top--;
st[++top]=id[i];
if(top>)p[top]=cross(st[top-],id[i]);
}
p[top+]=node(1ll<<,);
for(int i=;i<=n;i++)
if(ans[i]>)
{
int l=,r=top-,mid,pos=top;
while(l<=r)
{
mid=l+r>>;
if(a[st[mid]]>=a[i]||cross(st[mid],i)<=p[mid+])pos=mid,r=mid-;
else l=mid+;
}
s[++tot]=pii(a[st[pos]]>=a[i]?:cross(st[pos],i).a+,);
l=,r=top,pos=;
while(l<=r)
{
mid=l+r>>;
if(a[st[mid]]<=a[i]||p[mid]<=cross(st[mid],i))pos=mid,l=mid+;
else r=mid-;
}
if(a[st[pos]]>a[i])s[++tot]=pii(cross(st[pos],i).ceil(),-);
}
sort(s+,s+tot+);
for(int i=,j=,sum=;i<=top;i++)
{
while(j<=tot&&s[j].first<=p[i].ceil())sum+=s[j++].second;
if(sum<k)ans[st[i]]=k;
while(j<=tot&&s[j].first<=p[i+].a)
{
int p=j;
while(p<=tot&&s[p].first==s[j].first)sum+=s[p++].second;
if(sum<k)ans[st[i]]=k;
j=p;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%lld%lld",&a[i],&b[i]),id[i]=i,ans[i]=-;
sort(id+,id+n+,cmp);
for(int i=;i<=m;i++)solve(i);
for(int i=;i<=n;i++)printf("%d ",ans[i]);
}

[ZJOI2019]浙江省选(半平面交)的更多相关文章

  1. 【题解】Luogu P5328 [ZJOI2019]浙江省选

    原题传送门 看起来挺妙实际很暴力的一题 已知每个选手的分数都是平面上的直线 题目实际就是让我们求每条直线在整点处最大是第几大 我们考虑先对所有的直线进行半平面交(因为\(a_i\)都是正整数,所以比普 ...

  2. luogu P5328 [ZJOI2019]浙江省选

    传送门 每个人都可以看成一条直线\(y=ax+b\),所以我们要求的是每条线在整点处,上方线的数量的最小值(注意多条直线如果交于同一整点互不影响) 如果\(m=1\),其实只要求出半平面交,然后在半平 ...

  3. 【LuoguP5328】[ZJOI2019]浙江省选

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

  4. UVALive 4992 Jungle Outpost(半平面交)

    题意:给你n个塔(点)形成一个顺时针的凸包,敌人可以摧毁任何塔,摧毁后剩下的塔再组成凸包 在开始的凸包内选一点为主塔,保证敌人摧毁尽量多塔时主塔都还在现在的凸包内,求出最多摧毁的塔 题解:这题关键就是 ...

  5. 2018.10.15 bzoj4445: [Scoi2015]小凸想跑步(半平面交)

    传送门 话说去年的省选计算几何难度跟前几年比起来根本不能做啊(虽然去年考的时候并没有学过计算几何) 这题就是推个式子然后上半平面交就做完了. 什么? 怎么推式子? 先把题目的概率转换成求出可行区域. ...

  6. 【POJ 3525】Most Distant Point from the Sea(直线平移、半平面交)

    按逆时针顺序给出n个点,求它们组成的多边形的最大内切圆半径. 二分这个半径,将所有直线向多边形中心平移r距离,如果半平面交不存在那么r大了,否则r小了. 平移直线就是对于向量ab,因为是逆时针的,向中 ...

  7. 【BZOJ-2618】凸多边形 计算几何 + 半平面交 + 增量法 + 三角剖分

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 959  Solved: 489[Submit][Status] ...

  8. 【CSU1812】三角形和矩形 【半平面交】

    检验半平面交的板子. #include <stdio.h> #include <bits/stdc++.h> using namespace std; #define gg p ...

  9. 简单几何(半平面交+二分) LA 3890 Most Distant Point from the Sea

    题目传送门 题意:凸多边形的小岛在海里,问岛上的点到海最远的距离. 分析:训练指南P279,二分答案,然后整个多边形往内部收缩,如果半平面交非空,那么这些点构成半平面,存在满足的点. /******* ...

随机推荐

  1. 深入理解java虚拟机第五部分高效并发

    volatile是java虚拟机提供最轻量级的同步机制. volatile两个特性:1,保证同步的变量对所有线程是可见的.虽然对所有线程是即时可见的,但是却不保证原子性,也就是不保证线程安全,比如对于 ...

  2. 算法设计和分析(Prim算法构建最小生成树)

    问题: 给定无向图G(N,M)表明图G有N个顶点,M条边,通过Prim算法构造一个最小生成树 分析: 算法流程: 构造好的最小生成树就是step6 运行代码: #include<cstdio&g ...

  3. JavaWeb之搭建自己的MVC框架(三)

    1. 前言         在前两节的内容中,我们完成了一个基本的框架搭建.但是如果我们在前端请求中增加参数,我们要怎么传递到后台方法呢?接下来我们就来研讨这部分内容. 2. 实现         ( ...

  4. Java线程——线程之间的死锁

    一,什么是死锁? 所谓的死锁是指多个线程因为竞争资源而造成的一种僵局(相互等待),若无外力的作用,这些进程都不能向前推进. 二,死锁产生的条件? (1)互斥条件:线程要求对所分配的资源(如打印机)进行 ...

  5. this深度面试题2

    var name = "windows" var object = { name:"object", show:function(){ return funct ...

  6. 用CNN及MLP等方法识别minist数据集

    用CNN及MLP等方法识别minist数据集 2017年02月13日 21:13:09 hnsywangxin 阅读数:1124更多 个人分类: 深度学习.keras.tensorflow.cnn   ...

  7. node,npm,webpack,vue-cli模块化编程安装流程

    首先什么都不要管,先装环境. pip是万能的!!! 安装node: pip3 install node 安装npm:   pip3 install npm 安装webpack: npm install ...

  8. Django模型基础——(二)

    上篇博客主要讲了django中对数据库的增删改查,下面深入再讲解下对数据库的操作. 常用的查询方法 下面以表名为User为例 User.object.first() :返回表中第一条数据 User.o ...

  9. awk 中 RS,ORS,FS,OFS 区别与联系

    一,RS与ORS 1,RS是记录分隔符,默认的分隔符是\n,具体用法看下 [root@krlcgcms01 mytest]# cat test1     //测试文件 111 222 333 444 ...

  10. 大数据攻城狮之进阶技能-Github的使用

    引用百度百科中的介绍: github GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名GitHub. GitHub于2008年4月10日正式上线 ...