【题解】Luogu P5328 [ZJOI2019]浙江省选
原题传送门
看起来挺妙实际很暴力的一题
已知每个选手的分数都是平面上的直线
题目实际就是让我们求每条直线在整点处最大是第几大
我们考虑先对所有的直线进行半平面交(因为\(a_i\)都是正整数,所以比普通的还简单),我们珂以求出哪几个选手最高能拿到rak1
我们再考虑哪几个选手最高珂以拿到rak2
对剩下的人所表示的线段进行半平面交,我们珂以二分查找出之前已经删除的线段每个线段在哪个区间比现在的半平面边界高,打上标记(差分),进行排序,然后扫描线一遍,看到底有哪几个人上面的标记是1的,将这些人的答案标成2
以此类推,我们做m次半平面交,就能求出我们所需答案,时间复杂度\(O(mn\log n)\)
#include <bits/stdc++.h>
#define ll long long
#define N 100005
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline ll read()
{
register ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
struct num{
ll a,b,c;
num(){a=b=0,c=1;}
num(register ll x,register ll y)
{
if(y<0)
x=-x,y=-y;
a=x/y;
b=x%y;
c=y;
if(b<0)
b+=c,--a;
}
inline ll floor(){return a;}
inline ll ceil(){return a+(b>0);}
inline bool operator<(const num &x)const{return a==x.a?b*x.c<x.b*c:a<x.a;}
inline bool operator<=(const num &x)const{return a==x.a?b*x.c<=x.b*c:a<x.a;}
}p[N];
int n,m,id[N],s[N],top,tot,ans[N];
ll a[N],b[N];
pair<ll,int> S[N<<1];
inline num cross(register int x,register int y)
{
return num(b[y]-b[x],a[x]-a[y]);
}
inline void work(register int k)
{
p[top=tot=0]=num(0,1);
for(register int i=1;i<=n;++i)
if(ans[id[i]]==-1&&a[id[i]]>a[s[top]])
{
while(top&&cross(id[i],s[top]).floor()<p[top].ceil())
--top;
s[++top]=id[i];
if(top>1)
p[top]=cross(s[top-1],id[i]);
}
p[top+1]=num(1ll<<60,1);
for(register int i=1;i<=n;++i)
if(ans[i]>0)
{
int l=1,r=top-1,res=top;
while(l<=r)
{
int mid=l+r>>1;
if(a[s[mid]]>=a[i]||cross(s[mid],i)<=p[mid+1])
res=mid,r=mid-1;
else
l=mid+1;
}
S[++tot]=make_pair(a[s[res]]>=a[i]?0ll:cross(s[res],i).floor()+1,1);
l=2,r=top,res=1;
while(l<=r)
{
int mid=l+r>>1;
if(a[s[mid]]<=a[i]||p[mid]<=cross(s[mid],i))
res=mid,l=mid+1;
else
r=mid-1;
}
if(a[s[res]]>a[i])
S[++tot]=make_pair(cross(s[res],i).ceil(),-1);
}
sort(S+1,S+1+tot);
for(register int i=1,j=1,x=0;i<=top;++i)
{
while(j<=tot&&S[j].first<=p[i].ceil())
x+=S[j++].second;
if(x<k)
ans[s[i]]=k;
while(j<=tot&&S[j].first<=p[i+1].floor())
{
int l=j;
while(l<=tot&&S[l].first==S[j].first)
x+=S[l++].second;
if(x<k)
ans[s[i]]=k;
j=l;
}
}
}
inline bool cmp(register int x,register int y)
{
return a[x]<a[y]||a[x]==a[y]&&b[x]>b[y];
}
int main()
{
n=read(),m=read();
for(register int i=1;i<=n;++i)
a[i]=read(),b[i]=read(),id[i]=i,ans[i]=-1;
sort(id+1,id+1+n,cmp);
for(register int i=1;i<=m;++i)
work(i);
for(register int i=1;i<=n;++i)
write(ans[i]),putchar(' ');
return 0;
}
【题解】Luogu P5328 [ZJOI2019]浙江省选的更多相关文章
- luogu P5328 [ZJOI2019]浙江省选
传送门 每个人都可以看成一条直线\(y=ax+b\),所以我们要求的是每条线在整点处,上方线的数量的最小值(注意多条直线如果交于同一整点互不影响) 如果\(m=1\),其实只要求出半平面交,然后在半平 ...
- 【LuoguP5328】[ZJOI2019]浙江省选
题目链接 题意 给你一堆斜率和纵截距都为正的直线 ,求对于一个条直线是否存在一个 x 使得在这条直线在 x 处能是前 m 大,输出最高能够达到的排名(排名定义为在 x 处严格大于自己的直线条数+1) ...
- [ZJOI2019]浙江省选(半平面交)
一眼看上去就应该能用半平面交去做. 首先考虑怎么求可能得第1名的人:每个人的函数为直线,就是在所有人的半平面交中的上边界者即可获得第一名,这个可以单调队列求解. 再考虑如何求可能得第2名的人:满足2个 ...
- Luogu P5296 [北京省选集训2019]生成树计数
Luogu P5296 [北京省选集训2019]生成树计数 题目链接 题目大意:给定每条边的边权.一颗生成树的权值为边权和的\(k\)次方.求出所有生成树的权值和. 我们列出答案的式子: 设\(E\) ...
- [题解] Luogu P5446 [THUPC2018]绿绿和串串
[题解] Luogu P5446 [THUPC2018]绿绿和串串 ·题目大意 定义一个翻转操作\(f(S_n)\),表示对于一个字符串\(S_n\), 有\(f(S)= \{S_1,S_2,..., ...
- 「ZJOI2019」浙江省选
在八月来临前补完了zjoi2019 本来是想在八月前做完暑假作业的? 传送门 Description 给\(n\)条斜率为正的直线,询问每条直线是否在某处高度为前\(m\)名,如果是,询问最小排名 S ...
- 【题解】Luogu P5327 [ZJOI2019]语言
原题传送门 看到这种树上统计点对个数的题一般是线段树合并,这题也不出意外 先对这棵树进行树剖,对于每次普及语言,在\(x,y\)两点的线段树上的\(x,y\)两位置打\(+1\)标记,在点\(fa[l ...
- 【题解】Luogu P5279 [ZJOI2019]麻将
原题传送门 希望这题不会让你对麻将的热爱消失殆尽 我们珂以统计每种牌出现的次数,不需要统计是第几张牌 判一副牌能不能和,类似这道题 对于这题: 设\(f[i][j][k][0/1]\)表示前\(i\) ...
- Luogu P5279 [ZJOI2019]麻将
ZJOI2019神题,间接送我退役的神题233 考场上由于T2写挂去写爆搜的时候已经没多少时间了,所以就写挂了233 这里不多废话直接开始讲正解吧,我们把算法分成两部分 1.建一个"胡牌自动 ...
随机推荐
- ffmpeg结合SDL编写播放器(三)
接下来是解析影片的帧 /*** project.c ***/ #include<stdio.h> #include<libavcodec/avcodec.h> #include ...
- 驱动中遍历模块,以及获取ntoskrnl.exe基址
方法是基于PsLoadModuleList方式 驱动中遍历模块 一丶简介 简介: 进入内核了.遍历内核中使用的模块该怎么办. 其实在驱动中.我们的DriverEntry入口位置. 提供了两个参数. 一 ...
- 《jmeter接口自动化与性能实战-飞天小子.pdf》
Jmeter作为开源测试工具,以其轻便,功能齐全的优点,正越来越受到企业的重视.作为纯java的工具,它的扩展性无比强大,既可以做功能测试,也可以做性能测试:既支持接口层面的测试,也支持webdriv ...
- dubbo学习笔记(二)dubbo中的filter
转:https://www.cnblogs.com/cdfive2018/p/10219730.html dubbo框架提供了filter机制的扩展点(本文基于dubbo2.6.0版本). 扩展接口 ...
- Couldn't open file /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 解决办法(转)
使用yum update 更新的时候出现 “Couldn’t open file /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7” 这样的提示,去CentOS的官网:htt ...
- odoo开发笔记 -- docker容器打包到另一台服务器部署异常
场景描述: odoo.conf文件指定了数据库配置,如果docker打包的时候,没注意,新环境启动该镜像,会导致并没有连接本地的数据库,如果你配置文件中的数据库地址,当前这台服务器也可以访问到,那么问 ...
- django入门8之xadmin引入富文本和excel插件
django入门8之xadmin引入富文本和excel插件 Xadmin引入富文本 插件的文档 https://xadmin.readthedocs.io/en/docs-chinese/make_p ...
- 006-nginx.conf详解-error_page 使用
一.概述 nginx指令error_page的作用是当发生错误的时候能够显示一个预定义的uri 1.1.使用步骤 更改nginx.conf在http定义区域加入: proxy_intercept_er ...
- [译]在Ubuntu 18.04上安装pip
三步走: 1.更新源 sudo apt update 2.安装pip sudo apt install python3-pip 3.查看pip版本 pip3 --version pip 9.0.1 f ...
- 人脸识别(基于ArcFace)
我们先来看看效果 上面是根据图片检测出其中的人脸.每个人脸的年龄还有性别,非常强大 第一步: 登录https://ai.arcsoft.com.cn/,注册开发者账号,身份认证,注册应用,得到APPI ...