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,可以参 ...
- 6/14 Sprint2 看板和燃尽图
中间部分还需要改进 小组评分:(团队总分为80) 团队成员: 101丘娟同学:21 107杨晓霞同学:18 108周诗琦同学:22 124陈程同 ...
- Clojure学习笔记(二)——函数式编程
定义 “函数式编程”是一种编程范式(programming paradigm),即如何编写程序的方法论.主要思想是把运算过程尽量写成一系列嵌套的函数调用. 举例来说,现在有这样一个数学表达式: (1 ...
- python 多线程和多核
昨天在一个群里面遇到的,使用py做计算,只有1个CPU在跑任务,其它的怠工. 在py3以后,提供了:concurrent.futures mark 如下; 官方文档: 16.6. multiproce ...
- 火狐 about:config
1. 允许脚本关闭页面 dom.allow_scripts_to_close_windows -> true 2. 不要显示图片 permissions.default.image -> ...
- 在POM 4中,<dependency>中还引入了<scope>可以使用5个值
在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署.目前<scope>可以使用5个值: * compile,缺省值,适用于所有 ...
- windows下安装KeystoneJS
安装参考: http://keystonejs.com/zh/getting-started/ http://jsnoder.com/kjs/quickstart 安装前提条件: 安装 Node.JS ...
- 点击空白处隐藏div-阻止事件冒泡
$(" body").click(function(){ $("#div").hide(); }); $("button").click(f ...
- cocos2d-x 开头配置(Windows 平台)
工欲善其事,必先利其器. 要使用 cocos2d-x 引擎,就要配置(或者安装)引擎,到 cocos2d-x 官网下载页下载引擎,官网给了2.x和3.x两个版本,我使用的是3.6的版本,3.x的版本类 ...
- 在可以调用OLE之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute
导入导出功能,在调用ShowDialog时的错误,解决办法如下: WinForm窗体的入口点: /// <summary> /// 应用程序的主入口点. /// </summary& ...