bzoj4617: [Wf2016]Spin Doctor
Description
Input
Output
求出c=1的点的凸包,选出的S,T会使答案为一对包含了凸包的平行线间(含线上)的最小点数
当凸包只有一点时,若这个点不和其余c=1的点重合则答案为1,否则最坏情况下所有与凸包重合的点都被记入答案
当凸包上只有两点时,凸包为一条线段,线段上点数为所求
否则让平行线绕凸包类似旋转卡壳地扫描180度,对每个c=0的点,二分求出这个点进入和离开平行线时平行线对应的角度,得到每个点的出现区间,可以排序计算答案
#include<cstdio>
#include<algorithm>
#include<cmath>
char buf[],*ptr=buf-;
typedef long double ld;
typedef long long i64;
int _(){
int x=,f=,c=*++ptr;
while(c<)c=*++ptr;
while(c>)x=x*+c-,c=*++ptr;
return x*f;
}
int abs(int x){return x>?x:-x;}
struct pos{
int x,y;
int abs(){return (x>?x:-x)+(y>?y:-y);}
void fix(){if(y<||y==&&x<)x=-x,y=-y;}
}ps1[],ps2[],ps[];
bool operator<(pos a,pos b){return a.y!=b.y?a.y<b.y:a.x<b.x;}
bool operator==(pos a,pos b){return a.x==b.x&&a.y==b.y;}
pos operator+(pos a,pos b){return (pos){a.x+b.x,a.y+b.y};}
pos operator-(pos a,pos b){return (pos){a.x-b.x,a.y-b.y};}
i64 operator*(pos a,pos b){return i64(a.x)*b.y-i64(a.y)*b.x;}
i64 dot(pos a,pos b){return i64(a.x)*b.x+i64(a.y)*b.y;}
bool cmp(pos a,pos b){
i64 x=a*b;
return x?x>:a.abs()<b.abs();
}
int p1=,p2=,pp=,n,ans=;
ld as[];
const ld pi=.1415926535897932384626433832795l,_2pi=pi*;
void fix(ld&x,ld m){
while(x>=m)x-=m;
while(x<)x+=m;
}
struct ev{
pos a;
int t;
}es[];
bool operator<(ev a,ev b){
return a.a*b.a>;
}
int s0=,ep=;
int main(){
fread(buf,,sizeof(buf),stdin);
n=_();
for(int i=,x,y,c;i<n;++i){
x=_();y=_();c=_();
if(c)ps1[p1++]=(pos){x,y};
else ps2[p2++]=(pos){x,y};
}
int _p1=p1;
ans=p1;
std::sort(ps1,ps1+p1);
p1=std::unique(ps1,ps1+p1)-ps1;
std::sort(ps2,ps2+p2);
pos p0=ps1[];
for(int i=;i<p1;++i)ps1[i]=ps1[i]-p0;
std::sort(ps1+,ps1+p1,cmp);
ps[pp++]=(pos){,};
for(int i=;i<p1;++i){
while(pp>=&&(ps[pp-]-ps[pp-])*(ps1[i]-ps[pp-])>=)--pp;
ps[pp++]=ps1[i];
}
for(int i=;i<pp;++i)ps[i]=ps[i]+p0;
if(pp==){
if(_p1>)for(int i=;i<p2;++i)if(ps2[i]==ps[])++ans;
return printf("%d",ans),;
}
if(pp==){
for(int i=;i<p2;++i)if((ps2[i]-ps[])*(ps2[i]-ps[])==&&dot(ps2[i]-ps[],ps2[i]-ps[])<=)++ans;
return printf("%d",ans),;
}
ld xs=,ys=,a0;
for(int i=;i<pp;++i)xs+=ps[i].x,ys+=ps[i].y,ps[pp+i]=ps[i];
xs/=pp,ys/=pp;
ps[pp*]=ps[];
ps[pp*+]=ps[];
for(int i=;i<pp;++i)as[i]=std::atan2(ps[i].y-ys,ps[i].x-xs);
a0=as[];
for(int i=;i<pp;++i)fix(as[i]-=a0,_2pi);
for(int i=;i<p2;++i){
pos w=ps2[i];
ld a=std::atan2(w.y-ys,w.x-xs);
fix(a-=a0,_2pi);
int p=std::upper_bound(as,as+pp,a)-as;
if((ps[p-]-w)*(ps[p]-w)>=){
++ans;
continue;
}
ld b=a+pi;
fix(b,_2pi);
int p2=std::upper_bound(as,as+pp,b)-as;
int L=p,R=p2-,M;
if(L>R)R+=pp;
while(L<R){
M=L+R>>;
if((ps[M+]-w)*(ps[M]-w)>)L=M+;
else R=M;
}
pos _l=ps[L]-w;
_l.fix();
L=p2;R=p-;
if(L>R)R+=pp;
while(L<R){
M=L+R>>;
if((ps[M+]-w)*(ps[M]-w)<)L=M+;
else R=M;
}
pos _r=ps[L]-w;
_r.fix();
es[ep++]=(ev){_l,},es[ep++]=(ev){_r,-};
if(_l*_r<)++s0;
}
std::sort(es,es+ep);
int s1=s0;
for(int i=,j=;i<ep;){
for(;j<ep&&es[i].a*es[j].a==;++j);
for(;i<j;++i)s0+=es[i].t;
if(s0<s1)s1=s0;
}
printf("%d",ans+s1);
return ;
}
bzoj4617: [Wf2016]Spin Doctor的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- TAE words all
// vol 1 could do with sth rhinoplasty angst the wee small hours familial Munich gladi ...
- spin.js
$ajax提交,菊花加载的方式和位置: $.ajax({ type: "get", url: "http://www.xxx.com/test.html", b ...
- ros::spin() 和 ros::spinOnce() 区别及详解
版权声明:本文为博主原创文章,转载请标明出处: http://www.cnblogs.com/liu-fa/p/5925381.html 博主提示:本文基于ROS Kinetic Kame,如有更(g ...
- 为大家分享一个 Ajax Loading —— spin.js
我们在做Ajax 异步请求的时候,一般都会利用一个动态的 Gif 小图片来制作一个Ajax Loading ,以便增加用户体验. 今天在网上发现了一个 Spin.js ,该 js 脚本压缩后5k,可以 ...
- CF 84D Doctor(二分)
题目链接: 传送门 Doctor time limit per test:1 second memory limit per test:256 megabytes Description Th ...
- [杂谈] There is a Doctor in My Computer.
(p.s. 附带手写翻译,有错轻喷) Admin: Hi. (嗨) Doctor: How do you do? What brings you to see me? ...
- InnoDB Spin rounds per wait在>32位机器上可能为负
今天发现一个系统innodb的spin rounds per wait为负,感觉很奇怪,原来是个bug: For example (output from PS but we have no patc ...
- InnoDB Status Output – Buffer Pool and Spin Rounds
InnoDB has a good source of information about its status which can be requested every time you need ...
随机推荐
- CentOS PPTP配置FreeRADIUS+DaloRADIUS实现高级用户控制+流量控制
前提条件 阅读本文前,您需要搭建好PPTP,如果仍未搭建,可以参考:http://www.xj123.info/2301.html 如果您需要配置DaloRADIUS,那么您还需要安装LAMP,可以参 ...
- 【转】关于 Web GIS
以下部分选自2015-03-01出版的<Web GIS从基础到开发实践(基于ArcGIS API for JavaScript)>一书中的前言部分: Web GIS 概念于1994 年首次 ...
- break和continue的区别
break是结束整个循环体,continue是结束单次循环
- dpkg命令的用法
dpkg 是Debian package的简写,为”Debian“ 操作系统 专门开发的套件管理系统,用于软件的安装,更新和移除. 所有源自"Debian"的Linux的发行版都使 ...
- Java:多线程<二> 同步
由于多线程的访问出现延迟和线程的随机性,在使用多线程时往往会伴随安全性的问题,这些问题一旦出现将会是非常严重的.为了解决这种安全性问题,synchronized出现了. synchronized用法一 ...
- css关系选择器
1.包含选择符(E F) 选择所有被E元素包含的F元素,中间用空格隔开示例:<!DOCTYPE html><html> <head> <meta charse ...
- 荣品RP4412开发板摄像头驱动调用及对焦控制
1.关于更换不同摄像头驱动调用问题. 问:RP4412开发板,我用的摄像头640*480图像预览时OK的,但是我调用1280*720的初始化预览,摄像头没有图像了,是不是camera程序也需要修改? ...
- Quartz Spring与Spring Task总结
Spring对Quartz作了一个封装,同时,Spring自己也提供了一个任务定时器(spring-task),现把它总结一下. 对于Quartz,我们使用的时候主要是注重两个方面,一个是定时任 ...
- linux 实战使用,上传git 解决冲突
Last login: Fri Dec 18 09:48:55 on ttys000lidongxiaodeiMac:~ lidongxiao$ cd /Users/lidongxiao/Docume ...
- HTTP Referer 防外链
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理. if (Req ...