[ZJOI2019]浙江省选(半平面交)
一眼看上去就应该能用半平面交去做。
首先考虑怎么求可能得第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]浙江省选(半平面交)的更多相关文章
- 【题解】Luogu P5328 [ZJOI2019]浙江省选
原题传送门 看起来挺妙实际很暴力的一题 已知每个选手的分数都是平面上的直线 题目实际就是让我们求每条直线在整点处最大是第几大 我们考虑先对所有的直线进行半平面交(因为\(a_i\)都是正整数,所以比普 ...
- luogu P5328 [ZJOI2019]浙江省选
传送门 每个人都可以看成一条直线\(y=ax+b\),所以我们要求的是每条线在整点处,上方线的数量的最小值(注意多条直线如果交于同一整点互不影响) 如果\(m=1\),其实只要求出半平面交,然后在半平 ...
- 【LuoguP5328】[ZJOI2019]浙江省选
题目链接 题意 给你一堆斜率和纵截距都为正的直线 ,求对于一个条直线是否存在一个 x 使得在这条直线在 x 处能是前 m 大,输出最高能够达到的排名(排名定义为在 x 处严格大于自己的直线条数+1) ...
- UVALive 4992 Jungle Outpost(半平面交)
题意:给你n个塔(点)形成一个顺时针的凸包,敌人可以摧毁任何塔,摧毁后剩下的塔再组成凸包 在开始的凸包内选一点为主塔,保证敌人摧毁尽量多塔时主塔都还在现在的凸包内,求出最多摧毁的塔 题解:这题关键就是 ...
- 2018.10.15 bzoj4445: [Scoi2015]小凸想跑步(半平面交)
传送门 话说去年的省选计算几何难度跟前几年比起来根本不能做啊(虽然去年考的时候并没有学过计算几何) 这题就是推个式子然后上半平面交就做完了. 什么? 怎么推式子? 先把题目的概率转换成求出可行区域. ...
- 【POJ 3525】Most Distant Point from the Sea(直线平移、半平面交)
按逆时针顺序给出n个点,求它们组成的多边形的最大内切圆半径. 二分这个半径,将所有直线向多边形中心平移r距离,如果半平面交不存在那么r大了,否则r小了. 平移直线就是对于向量ab,因为是逆时针的,向中 ...
- 【BZOJ-2618】凸多边形 计算几何 + 半平面交 + 增量法 + 三角剖分
2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 959 Solved: 489[Submit][Status] ...
- 【CSU1812】三角形和矩形 【半平面交】
检验半平面交的板子. #include <stdio.h> #include <bits/stdc++.h> using namespace std; #define gg p ...
- 简单几何(半平面交+二分) LA 3890 Most Distant Point from the Sea
题目传送门 题意:凸多边形的小岛在海里,问岛上的点到海最远的距离. 分析:训练指南P279,二分答案,然后整个多边形往内部收缩,如果半平面交非空,那么这些点构成半平面,存在满足的点. /******* ...
随机推荐
- C++命名规范——谷歌规范
1.文件命名规则 文件名全部小写,可以含下划线或连字符,按项目约定命名,且尽量保证文件名明确.比如: cmd_save_player_info_class.cc ,my_use_full_class. ...
- Java基础——HashTable源码分析
HashTable是基于哈希表的Map接口的同步实现 HashTable中元素的key是唯一的,value值可重复 HashTable中元素的key和value不允许为null,如果遇到null,则返 ...
- Day 6:Vector类和实现Hashset以及登录窗口的模拟
LinkedList作业:生成扑克牌并且洗牌? import java.util.*; class Poker{ String color; String number; public Poker(S ...
- Mybatis基本配置(一)
1. Mybatis介绍 MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis 使用 ...
- POJ 3258:River Hopscotch 二分的好想法
River Hopscotch Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9326 Accepted: 4016 D ...
- LVS三种模式区别
参考文档 http://www.magedu.com/65436.html 名词:CIP 客户端IP地址 VIP:即DS服务器上的代理IP地址,也是客户端访问的执行IP地址 1.NAT模式 ①.客 ...
- 使用Python绘制新型冠状肺炎全国增长趋势图
截至1月28日24时,国家卫生健康委收到31个省(区.市)累计报告确诊病例5974例,现有重症病例1239例,累计死亡病例132例,累计治愈出院103例.现有疑似病例9239例.目前累计追踪到密切接触 ...
- php优惠券生成-去重
记录一次优惠券生成-去重 方法一 /** * 生成批量礼品消费券 */ public function giftCardAddOp() { //接收get值 $num = $_GET['gift_nu ...
- ipa提取png图片,windows下显示黑色
原因:ipa提取的png图片经过xcode特殊格式处理,在windows下查看会显示黑色 方法1:通过“ ipin.py文件”转化 过程: 1.安装python,需2.7版本,本文使用2.7.5 ...
- 基于springboot实现Ueditor并生成.html的示例
一.项目架构 二.项目代码 1.HtmlProductController.java package com.controller; import java.io.File; import java. ...