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 ...
随机推荐
- SQL中的xp_cmdshell拒绝访问
数据库备份作业的sql,,最后一步删除指定时间之前的文件夹.. 使用 xp_cmdshell 函数调用 RMDIR 命令删除过期文件夹,但返回拒绝访问.. 代码如下: DECLARE @PATH2 ...
- Cesium原理篇:Material【转】
https://www.cnblogs.com/fuckgiser/p/6171245.html Shader 首先,在本文开始前,我们先普及一下材质的概念,这里推荐材质,普及材质的内容都是截取自该网 ...
- 通过遍历而非排序求最值 python list in 时间复杂度 列表元素存在性
Write a function: def solution(A) that, given an array A of N integers, returns the smallest positiv ...
- esxi上为基于LVM的centos7的根目录扩容
概念:据说默认centos都是基于LVM的 LVM:LVM是逻辑盘卷管理(Logical Volume Manager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制. LVM 更加详细的说 ...
- Java基础 return 退出main方法的示例
JDK :OpenJDK-11 OS :CentOS 7.6.1810 IDE :Eclipse 2019‑03 typesetting :Markdown code ...
- Kotlin集合——Set集合
Kotlin集合——Set集合 转 https://www.jianshu.com/p/3c95d7729d69 Kotlin的集合类由两个接口派生:Collection和Map. Kotlin的 ...
- Leetcode: Rotated Digits
X is a good number if after rotating each digit individually by 180 degrees, we get a valid number t ...
- Python3基础 内置函数 hash
Python : 3.7.3 OS : Ubuntu 18.04.2 LTS IDE : pycharm-community-2019.1.3 ...
- 0.9.0.RELEASE版本的spring cloud alibaba sentinel限流、降级处理实例
先看服务提供方的,我们在原来的sentinel实例(参见0.9.0.RELEASE版本的spring cloud alibaba sentinel实例)上加上限流.降级处理,三板斧只需在最后那一斧co ...
- 软件定义网络基础---OpenFlow流表
一:流表 (一)流的概念 我们把同一时间经过同一网络中,具有某种共同特征或属性的数据,抽象为一个流 比如:我们将访问同一个地址的数据视为一个流 流一般是由网络管理员定义的,可以根据不同的流执行不同的策 ...