ZROI 19.08.02 计算几何

1.向量基础知识

  • \(atan2\)可以求极角,但是不是特别精确,在坐标接近\(10^{9}\)时会出锅,安全的做法是叉积。
  • 旋转、反射和平移等都可以抽象为矩阵,即,它们可以复合。(需要一些必修四知识)
  • 给一个序列,每个位置表示旋转、反射、平移中的一种,求\((x,y)\)经过序列\([l,r]\)的点。

线段树维护矩乘就好了,矩阵里需要带个常数位置。

  • Simpson积分

不会积分,告辞。

2.简单题

  • 求点\(p\)在直线\(p_1p_2\)上的投影。

投影就是点积,直接积就行了,必修四怎么学的。


  • 求点\(p\)在直线\(p_1p_2\)的反射点。

跟上面的一模一样。


  • 判断两个向量的\(5\)种位置关系。

叉积判出不共线的两种,剩下的直接比较横坐标就可以了。


  • 给两条直线,问它们是平行还是垂直还是都不是。

平行向量叉积为\(0\),垂直向量点积为\(0\)。


  • 判两条线段是否相交(不严格,端点交也算)。

跨立实验:对于一条线段,看另一条线段的两个点是否在它两侧,两边都是的话就对。

在一条直线上的情况会锅。

可以先判断外接矩形是否相交。(必要条件,不充分)


  • 求两条线段交点,保证有交(其实可以用上面的判一下)。

发现答案是\(A\cdot k_A\)或者\(B\cdot k_B\)的形式,列两个方程解就行了。

特判共线情况。


  • 求两条线段距离。(\(A,B\)各找一个点,使距离最小)。

发现一定取在某条线段的端点,转化为求点到线段距离。

计算\(A\)在\(p_1p_2\)上投影占\(p_1p_2\)比例,\(\leq 0\)离\(p_1\)最近,\(\geq 1\)离\(p_2\)最近,否则离投影点最近。


  • 逆时针给一个多边形,求面积。

一路叉积过去就好。


  • 逆时针给一个多边形,求是否凸。

一路叉积过去,两两边之间的叉积都要\(>0\)。


  • 逆时针给一个多边形,求一个点在多边形内、上还是外。

在多边形上很好判。

射线法,交奇数次在内部,偶数次在外部,但是会出现一些问题。

一种简单办法是把射线斜率设为无理数。

否则就要特判。硬点射线斜率是\(0\),且水平向右。

依次考虑每条边,平行的可以直接无视。

本质要解决的是穿过顶点的问题。

如果\(A\)在\(R\)上,且\(AB\)向上,或\(B\)在\(R\)上,且\(AB\)向下则算相交。


  • 给点集,求凸包。

烂大街经典问题。


  • 给凸包,求直径。

旋转卡壳。从横坐标最小和最大的点开始,每次前移一条边(类似双指针)。


  • 给凸多边形和一条射线,求凸多边形在射线左侧的面积。

扫一遍凸多边形,把符合要求的顶点和交点都拿出来求面积。



-\(n\)个点求最近点对。

分治,对于跨过中点的点对,只要找\(|x_i-x_j|\)不超过\(d\)的点即可。按\(y\)排序,每个点有贡献的点是常数个。


  • 圆之间的关系:相离(\(2+2\)条公切线),外切(\(1+2\)),相交(\(0+2\)),内切(\(0+1\)),包含(\(0+0\))。

  • 求圆和直线的交点。

求出弦心距,即可解出三角形,用夹角计算即可。


  • 求两个圆交点。

可以形成一个三边长为\(r_1,r_2,dis(o_1,o_2)\)的三角形,余弦定理解出夹角即可。


  • 点到圆的切点。

解三角形求夹角。


  • 求两个圆的公切线(\(0-4\)条)。

判一下\(0,1\)条公切线的情况。否则一定有两条外公切线。

由于公切线垂直于两条半径,可以平移一下,构造一个\(r_1-r_2,d,len\)的直角三角形,解三角形即可。

内公切线形成了两个相似三角形。


  • 求圆和多边形交的面积。

可以把多边形切成若干个有向三角形,转化成圆和三角形交的面积。

不妨把三角剖分的原点设为圆心。

如果整个三角形都在圆内,返回三角形面积。

如果整个\(AB\)都在圆外(垂线长\(\geq r\)),返回扇形面积。

否则按照\(AB\)与圆的交点切开,递归处理。发现最多递归常数次。


  • 最小圆覆盖。

经典问题,随机增量法。

3.较难题

  • \(n\)个圆盘从天而降,后面的会盖住前面的,求最后可见的轮廓线总长。\(n\leq 1000\)。

对每个圆盘求出后面的圆盘覆盖它的角度区间(求两个交点),并一下即可求出可见弧长。


  • 一棵有根树,每个点有\(a_i,b_i\),从某个点跳到子树某个点上,代价为\(a_i\cdot b_j\)。问每个点出发,跳到任意叶子节点最小代价。\(n \leq 10^5\)。

斜率优化的经典形式。启发式合并或者DSU on tree都可以。


  • 给若干个向量,每个向量有个代价。可以选若干个,用非负系数组合它们,要求能组合出任意向量,问最小代价。\(n\leq 2\times 10^5\)。

每个向量等价于一个射线。相当于要找三个向量,使得两两之间极角差$ <\pi$。

每个向量取反之后插进去,发现答案一定首尾之间\(<\pi\),并且答案形如“正反正”的三个向量。

特判四个互相垂直的情况。


  • \(n\)个点,问多少对顶点是这些点的三角形不相交(重合面积为\(0\)且无交点)。\(n \leq 2000\)。

结论:两个三角形不相交等价于它们有两条内公切线。

可以枚举两个点组成的公切线,求出两边点对数。


  • 圆反演:有一个圆作为基础,设为单位圆。每个点到圆心的向量方向不变,长度变为倒数。

  • \(n\)次操作,每次加入一个过原点的圆,或者询问一个点\((x,y)\)是否在所有圆内部。\(n\leq 5\times 10^5\)。

结论:过原点的圆反演后变成一条不过原点的直线。

在圆内部等价于反演后的点在反演后的直线特定的一侧。

动态半平面交,分治维护凸包即可。


  • 给定平面上不相交的两个圆和圆外一点,求过这个点且与两个圆外切的圆。

结论:不过原点的圆反演后还是不过原点的圆,且相交/相切等位置关系反演后仍然成立(因为同一个点反演后还是同一个点)。

圆反演后求公切线即可,需要一些特判。


  • 给出\(n\)个不相交的多边形,每次给出一个点,问它在哪个多边形内,或者不在任何一个多边形内,强制在线。\(n,q\leq 10^5,\sum points\leq 3\times 10^5\)。

多边形不相交是很强的限制。

硬点多边形的边是逆时针给出的。

对每个点找到竖直往上走最近的边,如果是从左往右则不在,否则在对应多边形内部。

如果可以离线,按横坐标扫描线一下,维护线段之间的上下位置关系。由于线段不相交,上下关系只会在插入删除时才会改变。用set维护就行了。

强制在线需要一个可持久化treap,不会写。

一大堆特判。


考虑一个二维平面,横轴时间,纵轴dfs序。

树剖以后变成\(m\log n\)条线段,求最早相交时间。

按\(x\)扫描线,set维护\(y\)的大小关系。

如果两条线段有交,它们一定在某个时刻在set中相邻,否则任意两条线段之间关系不会改变。

插入删除的时候check一下前驱后继即可。


  • 一个凸多边形,\(q\)组询问,给出\((x_i,y_i)\),求经过这一点的直线,把凸多边形面积平分,输出极角或无解。\(n\leq 10^4, q\leq 10^5\)。

设\(f(x)\)表示极角为\(x\)的射线左侧-右侧的面积。有\(f(0)=-f(\pi)\),所以必然存在零点,二分这个点即可。

考虑对叉积求前缀和,先二分出射线落在哪两条边上,然后内部的变化是线性的,可以直接算。

4.微积分在计算几何中的应用

这一段疯狂掉线……我太菜了。


  • 偏导数:多元函数只导其中一维。
  • 重积分:多元函数的每一维都积分,比如\(k\)维空间,对空间的每一个点都取一个函数值,取的足够细时有一个极限。
  • 曲线积分:把曲线参数化然后积分。
  • 闭合曲线的面积:掉线了,咕咕咕。
  • 一元函数的极值:极大不代表最大,只需要一个足够小的邻域,在邻域内最大。极值点导数为\(0\)。
  • 驻点:导数为\(0\)的点。极值点一定是驻点,驻点不一定是极值点。求一个函数的最大值,可以把所有驻点、不可导点都拉出来check一下。
  • 对于多元函数,可以对每一维偏导,然后硬点每个偏导都为\(0\),解方程就行了。
  • 可以把原函数进行修改,使得它在一些边界可导(\(|x|->x^2\))。
  • 拉格朗日乘数法:假设有若干\(g_i(x_1,…,x_n)=0\)的限制条件,在这种条件下最大化\(f(x_0,…,x_n)\)的值,可以设\(F(x_0,…,x_n,\lambda_0,…,\lambda_m)=f(x_0,…,x_n)+\sum_{j=0}^m\lambda_i g_i(x_1,…,x_n)\),然后对\(F\)的每一维偏导,利用上面的方法求解。
  • 曲线的切线、法平面:掉线了,咕咕咕。
  • 曲面的切平面、法线:掉线了,咕咕咕。

原文地址:https://www.cnblogs.com/suwakow/p/11375072.html

时间: 2024-11-06 13:42:25

ZROI 19.08.02 计算几何的相关文章

ZROI 19.08.02 杂题选讲

给出\(n\)个数,用最少的\(2^k\)或\(-2^{k}\),使得能拼出所有数,输出方案.\(n,|a_i|\leq 10^5\). 显然一个绝对值最多选一次.这个性质非常强. 如果所有都是偶数,可以直接除以\(2\). 否则\(1\)或\(-1\)必须选,暴力枚举选哪个然后递归,每层去重,发现最多只会递归\(\log a\)次.总复杂度\(O((n+a)\log n)\),等价于线段树上区间长度总和. \(n\)个数,每次可以花费\(1\)的代价给某个数\(+1\)或\(-1\),问变成不

ZROI 19.08.04模拟赛

传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. "这应该是正睿OI历史上第一次差评破百的比赛." "这说明来正睿集训的人越来越多了." "我很不能理解差评,因为在比赛开始前就有超过\(40\)个差评了." 天祺鸽鸽nb! A "这题标程是线性的,可是为什么没有出\(5\times 10^6\)呢?因为spj要带个\(\log\),这样就T了." \(100pts:\) 打表观察发现有解当且仅当\(\sum k

ZROI 19.08.12模拟赛

传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. "我发现问题的根源是大家都不会前缀和."--敦爷 A 敦爷spj写错了,差点把蒟蒻swk送走 \(50pts:\) 考虑不输出方案怎么做.显然是树形dp. 设\(f_{i,j,\{0/1/2\}}\)表示\(i\)的子树中,有\(j\)条链,根节点状态为:\(\{\)没选\(/\)选了向下的一条链\(/\)选了向下的两条链\(\}\)的最优解. 对于一棵子树,开始时只考虑根节点,依次合并每个儿子.合并时需要枚举父亲和儿子

ZROI 19.08.10模拟赛

传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. A \(20pts:\) 枚举操作序列然后暴力跑,复杂度\(O(6^n)\). \([50,80]pts:\) 枚举改成dfs,每层操作后还原.复杂度\(O(3^n)\). 全0或全1可以直接返回. 写法优秀可以过\(80pts\). \(100pts:\) 类似非递归fft的写法,bitrev后可以位运算优化. 最下面四层可以预处理,复杂度\(O(3^{n-4})\). 然后疯狂卡常就完事了( 然而由于swk人菜常数大,明明所有

ZROI 19.08.09模拟赛

传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. A \(70pts:\) 维护一个栈,从一侧向另一侧扫描,如果新加入的元素与当前栈顶相同,则出栈,否则进栈.显然一个子串是括号序列,当且仅当栈为空. 枚举起点,暴力模拟即可.复杂度\(O(n^2)\). \(100pts:\) 对于一个右端点,考虑哪些左端点可以和它匹配. 发现所有合法的左端点,两者栈的内容都是相等的,可以Hash判断. 实际上考虑每次加入字符时,只会在末尾变动一次,可以用trie树维护.复杂度\(O(\sigma

ZROI 19.08.11模拟赛

传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. dlstql,wsl A \(10pts:\) \(a=100,T=100\),对每个排列构造一个反的,一步到位即可. \(20pts:\) \(a=50\),构造\(1\)和所有元素交换的排列,实现交换\((v,u)\)可以令两者分别与\(1\)交换,选择排序即可. \(40pts:\) \(a=30\),构造前\(25\)个元素与\(1\)交换的排列,另有一个排列交换前\(25\)个与后\(25\)个元素. \(a=20\)时

ZROI 19.08.07模拟赛

传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. "正睿从来没有保证,模拟赛的题目必须原创." "文案不是我写的,有问题找喵老师去."--蔡老师 A R爷再次翻车,搞出来了一道六年前的CF题. \(100pts:\) 然而不是原题也很简单,斜率优化板子,单调队列搞一下就完事了. 也可以wqs二分,复杂度可以做到\(O(m\log m)\),\(与\)p\(无关.所以R爷差点把\)p$出到\(10^5\). B 本题乱搞做法非常多,所以R爷动用了权限来

ZROI 19.08.05模拟赛

传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. A \(21pts:\) 随便枚举,随便爆搜就好了. \(65pts:\) 比较显然的dp,设\(f_{i,j,k}\)表示在子树\(i\)中,两个赞助商分别选了\(j,k\)个的最优解. 对枚举的上下界卡的紧一点,按照树上背包的聚合分析,复杂度是\(O(n^3)\)的,可以通过. \(100pts:\) 观察数据范围可以发现,这题的子树大小限制可以抽象成一个经典的网络流模型. 跑一个最大费用流就好了. 我写丑了,每个点拆了\(5

ZROI 19.08.08模拟赛

传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. 首先恭喜swk今天翻车! "小心大样例演你."--天祺鸽鸽 果然swk今天被大样例演死了,天祺鸽鸽诚不欺我! A 这题标程是前几天ACM赛的双栈背包-- 然而可以排序之后直接背包,\(O(nm)\)随便过( B 菜 swk 菜 发现答案就是子串中最长border,即串长减去最短循环节. 每个字母是独立的,可以分开计算答案. 对第\(i\)个字母,设循环节循环次数为\(k\),在循环节内的长度为\(f_i\),剩余的长度为