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 ...
随机推荐
- python中main()函数写法
顶顶大名的Guido van Rossum(Python之父)推荐的main写法: #!/usr/bin/python import sys import getopt class Usage(Exc ...
- Yii批量添加的问题
使用Yii进行批量添加的时候,执行后会发现表中只插入了foreach循环的最后一条数据,而其它数据没有添加成功,那是因为内存地址中循环时新一条数据会覆盖前一条数据,解决办法如下: 第一种方法: < ...
- I/O多路复用 SELECT POLL -- 内核实现
等待队列 先补充个基础知识――等待队列 认识 定义 wait_queue_head_t wait_queue; 初始化 init_waitqueue_head(&wait_queue); 等待 ...
- 51nod 1051 最大子矩阵和(dp)
题目链接:51nod 1051 最大子矩阵和 实质是把最大子段和扩展到二维.读题注意m,n... #include<cstdio> #include<cstring> #inc ...
- SQL语句---nvl 用法
SQL语句---nvl 用法 一NVL函数是一个空值转换函数 NVL(表达式1,表达式2) 如果表达式1为空值,NVL返回值为表达式2的值,否则返回表达式1的值. 该函数的目的是把一个空值(nul ...
- python实现屏幕截图
from selenium import webdriver import time def capture(url, save_fn="capture.png"): browse ...
- 苹果IOS系统SVN命令 同样适用于linux系统
1.将文件checkout到本地目录svn checkout path(path是服务器上的目录)例如:svn checkout svn://192.168.1.1/pro/domain简写:svn ...
- 1410. Crack
http://acm.timus.ru/problem.aspx?space=1&num=1410 题目倒是不难,水题DP 就是题意理解起来有点困难,意思就是给你一段话,提取里面的单词 单词有 ...
- c++英文单词频度统计程序
英文单词频度统计程序(c++版) 写一个程序,分析一个文本文件(英文文章)中各个次出现的频率,并且把频率最高的十个词打印出来. 分析过程: (1) 简单设想大致分为两大步骤: 1.经过文本文件的读操 ...
- IT公司100题-25-求字符串中的最长数字串
问题描述: 实现一个函数,求出字符串中的连续最长数字串.例如输入”12345cbf3456″,输出”12345″. 函数原型为: void conti_num_max( const char * sr ...