15-16 ICPC europe J Saint John Festival (graham扫描法+旋转卡壳)
题意:给n个大点,m个小点$(n<=1e5,m<=5e5),问有多少个小点,存在3个大点,使小点在三个大点组成的三角形内。
解题思路:
首先,易证,若该小点在某三大点行成的三角形内,则该小点必然处在大点组成的凸包内。那么首先,现将大点形成的凸包计算出来,但是若对每个点进行暴力枚举,在最坏情况下,若凸包上点数太多并且脸黑不断找区间,复杂度会达到$O(nm)$,因此要对点是否在凸包内的判断过程进行优化。
将凸包划分为若干个三角形,我们可以先将这m个待判断的点进行极角排序,排序后,极角较大的点要么处在较小的点的逆时针方向的三角形内要么在同一个三角形内,要么两个点在同一三角形内。因此在点坐标转移时,采用旋转卡壳,所在的三角形区域也逆时针选择即可。而对于小点是否在三角形内,采用面积判断即可,为了防止爆精度推荐用行列式计算面积,时间复杂度$O(nlogn+mlogm+m)$
下面贴上AC代码。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pii;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rept(i,a,b) for(int i=a;i<=b;i++)
#define mes(a,b) memset(a,b,sizeof a)
#define pb push_back
#define dd(x) cout<<#x<<"="<<x<<" "
#define de(x) cout<<#x<<"="<<x<<"\n"
#define fi first
#define se second
#define mp make_pair
pii point[],small[];
pii operator -(const pii &s1,const pii &s2)
{
return mp(s1.fi-s2.fi,s1.se-s2.se);
}
int s[];
ll chaji(const pii &s1,const pii &s2)
{
return s1.fi*s2.se-s1.se*s2.fi;
}
bool comp(const pii &s1,const pii &s2)
{
if((s1.se<point[].se)+(s2.se<point[].se)==) return s1.se>s2.se;
ll x=chaji(s1-point[],s2-point[]);
if(x>||(x==&&abs(s1.fi-point[].fi)<abs(s2.fi-point[].fi))) return ;
else return ;
}
ll sqare(const pii &a,const pii &b,const pii &c)
{
return abs( (b.fi-a.fi)*(c.se-a.se) -(c.fi-a.fi)*(b.se-a.se) );
} int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n,m;
cin>>n;
rep(i,,n) cin>>point[i].fi>>point[i].se;
int p=;
rep(i,,n)
if( point[i].se<point[p].se||(point[i].se==point[p].se&&point[i].fi<point[p].fi) )
p=i;
swap(point[],point[p]);
//dd(point[0].fi);de(point[0].se);
sort(point+,point+n,comp);
int cnt=;
s[cnt++]=;
s[cnt++]=; rep(i,,n)
{
while(cnt>=&&chaji(point[s[cnt-]]-point[i],point[s[cnt-]]-point[i])>=) cnt--;
s[cnt++]=i;
} cin>>m;
rep(i,,m) cin>>small[i].fi>>small[i].se;
sort(small,small+m,comp);
int ans=;
p=; int start=;
while(start<m&&chaji(small[start]-point[s[]],point[s[]]-point[s[]])>) start++;
rep(i,start,m)
{
if(small[i].se<point[].se) break;
while(p<cnt-&&chaji( small[i]-point[s[]],point[s[p+]]-point[s[]] )< ) p++;
if(p==cnt-) break;
if(chaji( small[i]-point[s[]],point[s[p]]-point[s[]] )== )
{
if((small[i].fi<point[s[]].fi)+(small[i].fi<point[s[p]].fi)==) ans++;
continue;
}
else if(chaji( small[i]-point[s[]],point[s[p+]]-point[s[]] )<)
{
if((small[i].fi<point[s[]].fi)+(small[i].fi<point[s[p+]].fi)==) ans++;
continue;
}
if(sqare(point[s[]],point[s[p]],point[s[p+]])==sqare(point[s[]],point[s[p]],small[i])+sqare(point[s[]],point[s[p+]],small[i])+sqare(point[s[p]],point[s[p+]],small[i]))
ans++;
}
cout<<ans<<endl;
return ;
}
15-16 ICPC europe J Saint John Festival (graham扫描法+旋转卡壳)的更多相关文章
- Saint John Festival Gym - 101128J (凸包二分)
Problem J: Saint John Festival \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出\(n\)个大点,和\(m\ ...
- UVALive 7281 Saint John Festival (凸包+O(logn)判断点在凸多边形内)
Saint John Festival 题目链接: http://acm.hust.edu.cn/vjudge/contest/127406#problem/J Description Porto's ...
- 【计算几何】【凸包】【极角排序】【二分】Gym - 101128J - Saint John Festival
平面上n个红点,m个黑点,问你多少个黑点至少在一个红三角形内. 对红点求凸包后,转化为询问有多少个黑点在凸包内. 点在凸多边形内部判定,选定一个凸包上的点作原点,对凸包三角剖分,将其他的点极角排序之后 ...
- UVA - 13024 Saint John Festival 凸包+二分
题目链接:https://vjudge.net/problem/UVA-13024 题意:先给出\(L\)个点构造一个凸包,再给出\(S\)个点,询问有几个点在凸包内. 题解:判断点是否在凸包内的模板 ...
- UVA 13024: Saint John Festival(凸包+二分 ,判定多个点在凸包内)
题意:给定N个点,Q次询问,问当前点知否在N个点组成的凸包内. 思路:由于是凸包,我们可以利用二分求解. 二分思路1:求得上凸包和下凸包,那么两次二分,如果点在对应上凸包的下面,对应下凸包的上面,那么 ...
- Gym 101128J Saint John Festival(凸包 + 二分判点和凸包关系)题解
题意:给你一堆黑点一堆红点,问你有最多几个黑点能找到三个红点,使这个黑点在三角形内? 思路:显然红点组成的凸包内的所有黑点都能做到.但是判断黑点和凸包的关系朴素方法使O(n^2),显然超时.那么我现在 ...
- Python Cookbook(第3版)中文版:15.16 不确定编码格式的C字符串
15.16 不确定编码格式的C字符串¶ 问题¶ 你要在C和Python直接来回转换字符串,但是C中的编码格式并不确定. 例如,可能C中的数据期望是UTF-8,但是并没有强制它必须是. 你想编写代码来以 ...
- 剑指offer19:按照从外向里以顺时针的顺序依次打印出每一个数字,4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
1 题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印 ...
- linux 学习15 16 启动管理,备份和恢复
第十五讲 启动管理 . CentOS .x 启动管理 //此处指6.3 系统运行级别 .运行级别 运行级别 含 义 关机 单用户模式,可以想象为windows的安全模式,主要用于系统修复 //linu ...
随机推荐
- RabbitMQ入门学习系列(七) 远程调用RPC
快速阅读 生产者和消费者启动以后,都有一个接收事件,消费者是接收事件是处理调用方法以后等待生产者的返回,生产者的接收事件是处理接收生产者发送的消息,进行处理.消费者发送的时候要在回调队列中加入一个标识 ...
- [C++] wchar_t关键字使用方法
char 是单字符类型,长度为一个字节 wchar_t 是宽字符类型,长度为两个字节,主要用在国际 Unicode 编码中 举例: #include<iostream> using nam ...
- JVM 类加载器ClassLoader源码学习笔记
类加载 在Java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的. 类型可以是Class,Interface, 枚举等. Java虚拟机与程序的生命周期 在如下几种情况下,Java虚拟机 ...
- java 判断list是否为空
问题: 之前用 list!=null 来判断list是否为空,但发现,定义一个list后,即使里面并没有加入任何元素,返回的结果仍旧是 true, 其实,本意是希望在没有任何元素时,返回 false, ...
- cv2.warpAffine 参数详解
本文链接:https://blog.csdn.net/qq878594585/article/details/81838260本文为作者原创文章,未经同意严禁转载! opencv中的仿射变换在pyth ...
- MySQL 权限管理 用户管理
我使用的是 MariaDB 数据库 查看 MySQL 所有用户: select distinct concat('User: \'',user, '\'@\'', host, '\'') as que ...
- SpringBoot配置加载顺序
一般我们会将SpringBoot应用需要的配置内容放在项目工程中,然后通过spring.profiles.active或是通过Maven来实现多环境的支持.但是,当团队逐渐壮大,分工越来越细之后,往往 ...
- 测试一下windowsLiveWriter
一个是看看这个东西能不能发布出博客,还有一个就是准备开始写博客了,所以随便写个作为开始吧,我不想多说什么目标啊,什么的,所以就这一句简单的一句话就够了.
- Java PDF转换成图片并输出给前台展示
首先需要导入所需工具类 <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>fo ...
- phpexcel 导出excel无法打开,提示文件格式或文件名无效,文件损毁,解决办法
使用过很多次phpexcel了,有时需要保存文件到磁盘,有时需要浏览器弹出下载.保存到磁盘一半不会出现问题,关键是浏览器弹出保存,经常会发生导出的excel文件无法打开,提示文件格式或文件名无效,文件 ...