UPD:这个做法被hack了

题目大意:给你$n$个红点和$m$个黑点,问你至少需要保留多少个黑点,才能用由黑点组成的凸包包住所有红点。

数据范围:$n≤10^5$,$m≤500$

首先,我们将红点和黑点丢到一起,求一个凸包。凸包上的点能用黑点就用黑点,否则才用红点。

所有重点,三点共线的点,都会被删除。

如果求出的凸包上有红点,那么显然是包不住的,直接输出-1即可。

我们将在凸包上的黑点找出。

设$nxt[i]$表示凸包上第$i$号节点,能在顺时针方向上删除多少个凸包上的点,使得凸包依然能包含住全部的红点。

如果我们求出了这个东西,我们显然可以在$O(m)$的时间复杂度内,求出最少需要多少个点。

考虑如何求$nxt[i]$

我们对于由$i$和$i+nxt[i]$构成的连线,如果是合法的,那么显然要满足凸包外侧没有任何点。

我们可以对所有红点,都用叉积判一遍就可以了。

更新$nxt[i]$的过程可以用类似旋转卡壳的方式来搞,单次均摊是$O(n)$的。

(我场上$sb$了居然在求凸包,虽然也可以判,但是它T了)

这么搞时间复杂度是$O(nm)$的,实际上跑得飞快。

时间复杂度为$O((n+m)\log\ (n+m)+nm)$

 #include<bits/stdc++.h>
#define L long long
#define M 110000
#define INF 19890604
using namespace std; struct node{
L x,y;int type;
void rd(int Type){type=Type; scanf("%lld%lld",&x,&y);}
node(){x=y=type=;}
node(L X,L Y,int Type){x=X; y=Y; type=Type;}
friend node operator +(node a,node b){return node(a.x+b.x,a.y+b.y,);}
friend node operator -(node a,node b){return node(a.x-b.x,a.y-b.y,);}
friend L operator *(node a,node b){return a.x*b.y-a.y*b.x;}
friend bool operator ==(node a,node b){return a.x==b.x&&a.y==b.y;}
}a[M],s[M],b[],all[M],bas=node(,1e9,);
int n,m,cnt=,nm=; bool cmp(node x,node y){
if(x.x==y.x&&x.y==y.y) return x.type<y.type;
return (x-bas)*(y-bas)>;
}
void build(){
for(int i=;i<=nm;i++) if(all[].y>all[i].y) swap(all[],all[i]);
bas=all[]; sort(all+,all+nm+,cmp);
for(int i=;i<=nm;i++){
while(cnt>&&(s[cnt]-s[cnt-])*(all[i]-s[cnt-])<=)
cnt--;
if(cnt>&&s[cnt]==all[i]) cnt--;
s[++cnt]=all[i];
}
}
int nxt[M]={},vis[M]={};
int dfs(int x,int dep){
if(vis[x]) return printf("%d\n",dep-vis[x]);
vis[x]=dep;
dfs(nxt[x],dep+);
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) a[i].rd(),all[++nm]=a[i];
for(int i=;i<=m;i++) b[i].rd(),all[++nm]=b[i];
build();
for(int i=;i<=cnt;i++) if(s[i].type==) return printf("-1\n");
if(cnt==) return printf("1\n");
memset(b,,sizeof(b)); m=cnt;
for(int i=;i<=m;i++) b[i]=b[i+cnt]=s[i];
for(int i=,j=;i<=m;i++){
while(){
if(j==i) j++;
for(int k=;k<=n;k++)
if((a[k]-b[i])*(b[j]-b[i])>)
goto loop;
j++;
}
loop:;
nxt[i]=(j-+m)%m+;
}
dfs(,);
}

【xsy2305】喽 计算几何的更多相关文章

  1. ACM/ICPC 之 计算几何入门-叉积-to left test(POJ2318-POJ2398)

    POJ2318 本题需要运用to left test不断判断点处于哪个分区,并统计分区的点个数(保证点不在边界和界外),用来做叉积入门题很合适 //计算几何-叉积入门题 //Time:157Ms Me ...

  2. HDU 2202 计算几何

    最大三角形 Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  3. ACM 计算几何中的精度问题(转)

    http://www.cnblogs.com/acsmile/archive/2011/05/09/2040918.html 计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模 ...

  4. hdu 2393:Higher Math(计算几何,水题)

    Higher Math Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. sdut 2603:Rescue The Princess(第四届山东省省赛原题,计算几何,向量旋转 + 向量交点)

    Rescue The Princess Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 Several days ago, a b ...

  6. [知识点]计算几何I——基础知识与多边形面积

    // 此博文为迁移而来,写于2015年4月9日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vxaq.html 1.前言 ...

  7. POJ 1106 Transmitters(计算几何)

    题目链接 切计算几何,感觉计算几何的算法还不熟.此题,枚举线段和圆点的直线,平分一个圆 #include <iostream> #include <cstring> #incl ...

  8. TYVJ计算几何

    今天讲了计算几何,发几道水水的tyvj上的题解... 计算几何好难啊!@Mrs.General....怎么办.... 这几道题都是在省选之前做的,所以前面的Point运算啊,dcmp啊,什么什么的,基 ...

  9. 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点

    平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...

随机推荐

  1. 22. Generate Parentheses产生所有匹配括号的方案

    [抄题]: Given n pairs of parentheses, write a function to generate all combinations of well-formed par ...

  2. 14. pt-kill

    pt-kill h=192.168.100.101,P=3306,u=admin,p=admin \--match-user "user01" \--match-host &quo ...

  3. 1.3eigen中数组类和系数的运算

    1.3数组类和系数的运算 与矩阵类只适用与线性代数运算相反,数组类提供通用的数组类,能不利用线性代数的知识来对系数进行操作,比如对每个系数加上一个常数,或者乘上两个数组的系数. 1.数组类型 跟矩阵类 ...

  4. day30

    作业 #__author : 'liuyang' #date : 2019/4/11 0011 下午 12:36 # 这两天 1.软件开发规范 不写 没法做新作业 #2. 认证+上传 +下载 + 校验 ...

  5. 《Linux就该这么学》第四天课程

     秦时明月经典语录: 侠道:五步之内,百人不当.十年磨剑,一孤侠道——荆轲 我发了一些课堂笔记,供你们参考 原创地址:https://www.linuxprobe.com/chapter-03.htm ...

  6. 2019.02.11 bzoj4767: 两双手(组合数学+容斥dp)

    传送门 题意简述:你要从(0,0)(0,0)(0,0)走到(ex,ey)(ex,ey)(ex,ey),每次可以从(x,y)(x,y)(x,y)走到(x+ax,y+ay)(x+ax,y+ay)(x+ax ...

  7. python基础循环

    1.使用while循环输入1234568910 n = 1 while n < 11: if n == 7: pass else: print(n) n = n + 1 2.求1 - 100的所 ...

  8. MUI的一些笔记

    自定义图标 https://www.iconfont.cn选择图标添加入购物车 进入项目管理下载需要的图标压缩包之后按照自己的需求进行html的操作 事件绑定 mui(dom)on( event , ...

  9. python运算符优先级

    下面这个表给出Python的运算符优先级,从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合).这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算列在表上部的运算符. ...

  10. python模块:json

    r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of JavaScri ...