【题解】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.建一个"胡牌自动 ...
随机推荐
- nginx之fastcgi配置参数及其缓存
CGI的由来 最早的Web服务器只能简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动 ...
- 你真的知道Java中boolean类型占用多少个字节吗?
为什么要问这个问题,首先在Java中定义的八种基本数据类型中,除了其它七种类型都有明确的内存占用字节数外,就boolean类型没有给出具体的占用字节数,因为对虚拟机来说根本就不存在 boolean 这 ...
- robotframework 文档
http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#post-processing-outputs
- [技术博客]使用adb命令获取app(游戏)错误和警告日志
adb命令的使用 直接在命令行中输入: adb logcat *:W 注意:这句命令的意思是显示所有优先级大于等于警告(Warning)的日志,查找崩溃问题一般用: adb logcat *:E 注意 ...
- PhastCons | 序列保守性打分
这是一个进化学上的概念,基因组的序列是不断进化而来的,根据45个脊椎动物的基因组序列,通过多重比对,我们就可以知道人类基因组上每个位置的保守性,一些高度保守的区域可以做非常有意思的下游分析. This ...
- 对数损失函数logloss详解和python代码
python机器学习-乳腺癌细胞挖掘(博主亲自录制视频)https://study.163.com/course/introduction.htm?courseId=1005269003&ut ...
- mysql原生sql处理,按逗号拆分列为多行
举例: id value 1 1,2,3,4 2 2,3,4,5,6 拆分成: id value 1 1 2 2 3 3 4 4 5 5 6 6 ),) ) distinct:去重复操作 a.valu ...
- MQTT研究之EMQ:【EMQX使用中的一些问题记录(3)】
EMQX功能强大,但是帮助信息或者可用资料的确有限,遇到个问题,比较难找到处理的头绪,今天,我要记录的是,使用中出现EMQX宕机,但是呢,启动也启动不了. 今天记录的内容,就以操作EMQX 3.2.3 ...
- cheerio 服务器端的jquery
cheerio https://cheerio.js.org/ Fast, flexible, and lean implementation of core jQuery designed spec ...
- Qt编写控件属性设计器
一.前言 自从研究Qt编写自定义控件以来,一发不可收拾,越多越多人有类似的需求找我定制控件,陆陆续续写了上百个控件,目前已超过150个,于是逐渐衍生了另外一个需求,提供一个控件属性设计器,类似QtDe ...