题意:给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扫描法+旋转卡壳)的更多相关文章

  1. Saint John Festival Gym - 101128J (凸包二分)

    Problem J: Saint John Festival \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出\(n\)个大点,和\(m\ ...

  2. UVALive 7281 Saint John Festival (凸包+O(logn)判断点在凸多边形内)

    Saint John Festival 题目链接: http://acm.hust.edu.cn/vjudge/contest/127406#problem/J Description Porto's ...

  3. 【计算几何】【凸包】【极角排序】【二分】Gym - 101128J - Saint John Festival

    平面上n个红点,m个黑点,问你多少个黑点至少在一个红三角形内. 对红点求凸包后,转化为询问有多少个黑点在凸包内. 点在凸多边形内部判定,选定一个凸包上的点作原点,对凸包三角剖分,将其他的点极角排序之后 ...

  4. UVA - 13024 Saint John Festival 凸包+二分

    题目链接:https://vjudge.net/problem/UVA-13024 题意:先给出\(L\)个点构造一个凸包,再给出\(S\)个点,询问有几个点在凸包内. 题解:判断点是否在凸包内的模板 ...

  5. UVA 13024: Saint John Festival(凸包+二分 ,判定多个点在凸包内)

    题意:给定N个点,Q次询问,问当前点知否在N个点组成的凸包内. 思路:由于是凸包,我们可以利用二分求解. 二分思路1:求得上凸包和下凸包,那么两次二分,如果点在对应上凸包的下面,对应下凸包的上面,那么 ...

  6. Gym 101128J Saint John Festival(凸包 + 二分判点和凸包关系)题解

    题意:给你一堆黑点一堆红点,问你有最多几个黑点能找到三个红点,使这个黑点在三角形内? 思路:显然红点组成的凸包内的所有黑点都能做到.但是判断黑点和凸包的关系朴素方法使O(n^2),显然超时.那么我现在 ...

  7. Python Cookbook(第3版)中文版:15.16 不确定编码格式的C字符串

    15.16 不确定编码格式的C字符串¶ 问题¶ 你要在C和Python直接来回转换字符串,但是C中的编码格式并不确定. 例如,可能C中的数据期望是UTF-8,但是并没有强制它必须是. 你想编写代码来以 ...

  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 则依次打印 ...

  9. linux 学习15 16 启动管理,备份和恢复

    第十五讲 启动管理 . CentOS .x 启动管理 //此处指6.3 系统运行级别 .运行级别 运行级别 含 义 关机 单用户模式,可以想象为windows的安全模式,主要用于系统修复 //linu ...

随机推荐

  1. T-MAX组--项目冲刺(第四天)

    THE FOURTH DAY 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 T-MAX组--项目冲刺(第四天) 团队名称 T-M ...

  2. Scikit-Learn 机器学习笔记 -- 线性回归、逻辑回归、softma

      import numpy as np from matplotlib import pyplot as plt # 创建线性回归数据集 def create_dataset(): X = 2 * ...

  3. python TypeError: unsupported operand type(s) for +: 'geoprocessing value object' and 'str'

    TypeError: unsupported operand type(s) for +: 'geoprocessing value object' and 'str' if self.params[ ...

  4. ubuntu取消自动登录

    /etc/lightdm/lightdm.conf.d/50-nvidia.conf 注释 autologin-user=<YOUR USER>

  5. useReducer代替Redux小案例-2(八)

    通过上节课的学习,用useContext实现了Redux状态共享的能力,这节课看一下如何使用useReducer来实现业务逻辑的控制.需要注意的是这节课的内容是接着上节课的,需要你把上节课的代码部分完 ...

  6. JVM 字节码的结构

    编译的.class文件,可以用javap进行反编译 javap Test.class javap -c Test.class javap -verbose Test.class 1.创建MyTest1 ...

  7. 创建WebApi Odata v3 终结点

    开放数据协议(OData) 是用于 web 的数据访问协议. OData 提供统一的方法来构造数据. 查询的数据和操作该数据集通过 CRUD 操作 (创建. 读取. 更新和删除). OData 支持 ...

  8. 从0开始学爬虫2之json的介绍和使用

    从0开始学爬虫2之json的介绍和使用 Json 一种轻量级的数据交换格式,通用,跨平台 键值对的集合,值的有序列表 类似于python中的dict Json中的键值如果是字符串一定要用双引号 jso ...

  9. aar api 导出

    import fsys; import math; var pidMap = {}; math.randomize(); fsys.enum( "~\lib", "*.* ...

  10. k8s记录-下载k8s相关二进制包(一)

    1)软件清单操作系统:CentOS7Kubernetes版本:v1.14.2flannel:v0.10.0ectd3:v3.3.11Docker版本:v18.09.0-ceDocker-compose ...