传送门

每个人都可以看成一条直线\(y=ax+b\),所以我们要求的是每条线在整点处,上方线的数量的最小值(注意多条直线如果交于同一整点互不影响)

如果\(m=1\),其实只要求出半平面交,然后在半平面交上的线的答案就是\(1\).然后是\(m=2\),先把排名\(=1\)的线拿走,那么剩下的线如果排名可以为\(2\),那么至少应该在剩下的线的半平面交上.然后对于所有算过的线,他们都可以覆盖半平面交上的一段连续区间,可以使用二分求出覆盖的区间端点,然后就是找出在半平面交上的区域被上述区间覆盖的次数为1的线段更新答案,可以从左往右扫一遍求出,我这里用的是线段树.剩下的以此类推就好了

注意细节较多

// luogu-judger-enable-o2
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db long double using namespace std;
const int N=1e5+10;
const db eps=1e-10;
LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
struct point
{
db x,y;
point(){}
point(db nx,db ny){x=nx,y=ny;}
point operator - (const point &bb) const {return point(x-bb.x,y-bb.y);}
db operator ^ (const point &bb) const {return x*bb.y-y*bb.x;}
};
struct line
{
db k,b;
int i;
bool operator < (const line &bb) const {return fabs(k-bb.k)>eps?k<bb.k:b<bb.b;}
}a[N],p[N],st[N];
point jiao(line a,line b){db xx=(a.b-b.b)/(b.k-a.k),yy=a.k*xx+a.b;return point(xx,yy);}
db nx[N];
int n,m,an[N],tl,tp;
LL li[N][2],q[N][2],cg[N][2],bb[N<<2],mm;
int mi[N<<4],tg[N<<4],va[N];
void psup(int o){mi[o]=min(mi[o<<1],mi[o<<1|1]);}
void ad(int o,int x){mi[o]+=x,tg[o]+=x;}
void psdn(int o){if(tg[o]) ad(o<<1,tg[o]),ad(o<<1|1,tg[o]),tg[o]=0;}
void modif(int o,int l,int r,int ll,int rr)
{
if(ll<=l&&r<=rr){ad(o,1);return;}
psdn(o);
int mid=(l+r)>>1;
if(ll<=mid) modif(o<<1,l,mid,ll,rr);
if(rr>mid) modif(o<<1|1,mid+1,r,ll,rr);
psup(o);
}
int quer(int o,int l,int r,int ll,int rr)
{
if(ll<=l&&r<=rr) return mi[o];
psdn(o);
int an=1<<29,mid=(l+r)>>1;
if(ll<=mid) an=min(an,quer(o<<1,l,mid,ll,rr));
if(rr>mid) an=min(an,quer(o<<1|1,mid+1,r,ll,rr));
psup(o);
return an;
} int main()
{
nx[0]=-1e18;
n=rd(),m=rd();
for(int i=1;i<=n;++i)
{
an[i]=-1;
li[i][0]=rd(),li[i][1]=rd();
}
int nn;
for(int h=1;h<=m;++h)
{
sort(p+1,p+tl+1);
nn=0;
for(int i=1;i<=n;++i)
if(an[i]==-1) a[++nn]=(line){li[i][0],li[i][1],i};
if(!nn) break;
sort(a+1,a+nn+1);
a[nn+1].k=-1;
tp=0;
for(int i=1;i<=nn;++i)
{
if(a[i].k==a[i+1].k) continue;
while(tp>1&&jiao(a[i],st[tp]).y-jiao(a[i],st[tp-1]).y<-eps) --tp;
st[++tp]=a[i];
}
mm=0;
db xx=0;
for(int i=1;i<=tp;++i)
{
nx[i]=i<tp?jiao(st[i],st[i+1]).x:1e18;
q[i][0]=max((LL)(fabs(xx-floor(xx+0.5))<eps?(xx+0.5):ceil(xx)),0ll);
q[i][1]=max((LL)(fabs(nx[i]-floor(nx[i]+0.5))<eps?(nx[i]+0.5):floor(nx[i])),-1ll);
xx=nx[i];
bb[++mm]=q[i][0],bb[++mm]=q[i][1];
}
for(int i=1;i<=tl;++i)
{
//if(i==67) {int Q=5e8;while(Q--);}
int l=1,r=tp,z=tp;
while(l<=r)
{
int mid=(l+r)>>1;
if(p[i].k<=st[mid].k) z=mid,r=mid-1;
else l=mid+1;
}
int zz=0;
l=1,r=z-(p[i].k<=st[z].k);
while(l<=r)
{
int mid=(l+r)>>1;
xx=jiao(p[i],st[mid]).x;
if(xx>nx[mid-1]-eps) zz=mid,l=mid+1;
else r=mid-1;
}
if(zz)
{
xx=jiao(p[i],st[zz]).x;
//if((LL)(xx+0.5)==3149034259) {int Q=5e8;while(Q--);}
cg[i][0]=(LL)floor(xx)+1;
}
else cg[i][0]=0;
zz=0;
l=z+(p[i].k>=st[z].k),r=tp;
while(l<=r)
{
int mid=(l+r)>>1;
xx=jiao(p[i],st[mid]).x;
if(xx<nx[mid]+eps) zz=mid,r=mid-1;
else l=mid+1;
}
if(zz)
{
xx=jiao(p[i],st[zz]).x;
cg[i][1]=(LL)ceil(xx)-1;
}
else cg[i][1]=1e18;
bb[++mm]=cg[i][0],bb[++mm]=cg[i][1];
//printf("%lld %lld\n",cg[i][0],cg[i][1]);
}
sort(bb+1,bb+mm+1),mm=unique(bb+1,bb+mm+1)-bb-1;
nn=mm;
for(int i=2;i<=nn;++i)
if(bb[i]-bb[i-1]>1) bb[++mm]=(bb[i]+bb[i-1])>>1;
sort(bb+1,bb+mm+1),mm=unique(bb+1,bb+mm+1)-bb-1;
for(int i=0;i<=(mm<<2);++i) mi[i]=tg[i]=0;
for(int i=1;i<=tl;++i)
{
cg[i][0]=lower_bound(bb+1,bb+mm+1,cg[i][0])-bb;
cg[i][1]=lower_bound(bb+1,bb+mm+1,cg[i][1])-bb;
modif(1,1,mm,cg[i][0],cg[i][1]);
}
int mx=1<<29;
for(int i=1;i<=tp;++i)
{
//if(h==2&&st[i].i==75849){int Q=5e8;while(Q--);}
q[i][0]=lower_bound(bb+1,bb+mm+1,q[i][0])-bb;
q[i][1]=lower_bound(bb+1,bb+mm+1,q[i][1])-bb;
va[i]=q[i][0]<=q[i][1]?quer(1,1,mm,q[i][0],q[i][1]):1<<29;
mx=min(mx,va[i]);
//if(va[i]<n)printf("%d\n",st[i].i);
}
h=mx+1;
if(h>m) break;
for(int i=1;i<=tp;++i)
if(va[i]+1==h) an[st[i].i]=h,p[++tl]=st[i]/*,printf("%d %d\n",st[i].i,h)*/;
//puts("---");
}
for(int i=1;i<=n;++i) printf("%d ",an[i]);
return 0;
}

luogu P5328 [ZJOI2019]浙江省选的更多相关文章

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

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

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

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

  3. [ZJOI2019]浙江省选(半平面交)

    一眼看上去就应该能用半平面交去做. 首先考虑怎么求可能得第1名的人:每个人的函数为直线,就是在所有人的半平面交中的上边界者即可获得第一名,这个可以单调队列求解. 再考虑如何求可能得第2名的人:满足2个 ...

  4. Luogu P5296 [北京省选集训2019]生成树计数

    Luogu P5296 [北京省选集训2019]生成树计数 题目链接 题目大意:给定每条边的边权.一颗生成树的权值为边权和的\(k\)次方.求出所有生成树的权值和. 我们列出答案的式子: 设\(E\) ...

  5. 「ZJOI2019」浙江省选

    在八月来临前补完了zjoi2019 本来是想在八月前做完暑假作业的? 传送门 Description 给\(n\)条斜率为正的直线,询问每条直线是否在某处高度为前\(m\)名,如果是,询问最小排名 S ...

  6. Luogu P5279 [ZJOI2019]麻将

    ZJOI2019神题,间接送我退役的神题233 考场上由于T2写挂去写爆搜的时候已经没多少时间了,所以就写挂了233 这里不多废话直接开始讲正解吧,我们把算法分成两部分 1.建一个"胡牌自动 ...

  7. luogu P3226 [HNOI2012]集合选数

    luogu 因为限制关系只和2和3有关,如果把数中2的因子和3的因子都除掉,那剩下的数不同的数是不会相互影响,所以每次考虑剩下的数一样的一类数,答案为每类数答案的乘积 如果选了一个数,那么2的因子多1 ...

  8. Luogu P5280 [ZJOI2019]线段树

    送我退役的神题,但不得不说是ZJOIDay1最可做的一题了 先说一下考场的ZZ想法以及出来后YY的优化版吧 首先发现每次操作其实就是统计出增加的节点个数(原来的不会消失) 所以我们只要统计出线段树上每 ...

  9. Luogu P5327 [ZJOI2019]语言

    ZJOI2019Day2的温暖题,然后考场上只会大常数的\(O(n\log^3 n)\),就懒得写拿了60pts走人 首先我们简化题意,容易发现每个点能到达的点形成了一个联通块,我们只需要统计出这个联 ...

随机推荐

  1. Vue之vue中的data为什么是一个函数+vue中路径别名alias设置

    问题描述 为什么在vue组件中,我们的data属性必须是一个函数,new Vue()中的data除外,因为new Vue中只有一个data属性. 原因 因为我们能抽离出来的组件,肯定是具有复用性的,它 ...

  2. java高级面试题汇总(复习)从最基础的往上复习,每天定期更新。

    每天搬一点砖,总有一天成为大牛! 看问题的时候请不要立马去翻答案,多想想. 看完答案可以问问为什么,尝试拓展!一起加油吧! 每个答案后面都有一个小彩蛋(一个以上的拓展问题),钻研让你先人一步. jav ...

  3. SQL 表 数据备份

    insert into SMTTemporarySave select * from [MSV0CIMDB].[PICS_20170706].dbo.SMTTemporarySave

  4. Reactjs之实现js跳转路由

    1.新增知识 /* 实现js跳转路由:https://reacttraining.com/react-router/web/example/auth-workflow 1.要引入Redirect im ...

  5. vsftp软件安装部署

    1.安装vsftp yum install -y vsftpd db4-utils2.默认可以支持系统用户账号远程登录.不安全,建立虚拟账号体系为好.或者在服务器端对vsftpd.conf配置文件进行 ...

  6. PHP结合Ueditor并修改图片上传路径 微信小程序 拼接域名显示图片

    前言 在使用UEditor编辑器时,一般我们都是需要修改默认的图片上传路径的,下面是我整理好的修改位置和方法供大家参考. 操作 Ueditor PHP版本本身自带了一套上传程序,我们可以在此基础中,找 ...

  7. apache虚拟目录配置实例

    apache虚拟目录配置实例 一.首先,开启虚拟主机配置 在文件httpd.conf中找到: include conf/extra/httpd-vhosts.conf #开启 二.对httpd-vho ...

  8. asp.net 配置 web.config 禁用VS2013自带的Browser Link功能

    我的字符被截断了 然后,我修改了下 web.config 的配置,在appSettings节点里加了这个,如下: <appSettings><add key="vs:Ena ...

  9. DocX 在文档中插入图片时,为什么不能按实际设置的大小插入,而Spire.Doc却可以

    我的目标目标要求:将一个图片插入到页面中,页面边界为0,使用下面的代码去实现(button1UseDocX_Click函数),生成的文档不能达到目的.而使用Spire.Doc却能达到目的button1 ...

  10. switch-case的选择用法

    企业发放的奖金根据利润提成.利润I低于或等于100000元的,奖金可提0.1:利润高于100000元,低于200000(100000<I<=200000)时,低于100000元的部分按10 ...