凸包

【凸包】【Andrew算法】牛客 —message

…衆ロ難τιáo~ 提交于 2019-11-29 12:18:38
前置知识点 凸包: 概念 示例图(一) 1  点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。右图中由红色 线段 表示的多边形就是点集Q={p0,p1,...p12}的凸包。 2  一组平面上的点,求一个包含所有点的最小的 凸多边形 ,这就是凸包问题了。这可以形象地想成这样:在地上放置一些不可移动的木桩,用一根绳子把他们尽量紧地圈起来,并且为凸边形,这就是凸包了。 ——百度百科 Andrew 算法 是一种求解凸包的一种基本算法 具体过程还不会,等本菜鸡学会了再回来填坑 题意: 有 n 条直线 y=ax+b(a ≠ 0并且总是存在)。 m 次询问,每次询问给出一条直线 y=cx+d,求该直线与已知直线中交点横坐标最大的值是多少,如果没有交点则输出 "No cross"。 学习博客: https://blog.csdn.net/xbb224007/article/details/81158026 讲的超级详细,建议去学习 题解: 有两条直线 y=a*x+b y=c*x+d => x= -(b-d)/(a-c) 这样问题求x的最大值就转化成了求斜率的最小值 这时候就根据凸包求解即可 具体讲解请看上述推荐博客 #include<iostream> #include<algorithm> #include<cmath> #include

【动态凸包】Codeforces - 70 - D - Professor's task

拥有回忆 提交于 2019-11-29 06:31:57
题目链接 https://codeforces.com/contest/70/problem/D 题意 有两种操作: 平面上添加一个点 询问一个点,是否在已添加点形成的凸包内 题解 用set维护上凸包和下图包维护即可, 主要是一些细节的处理比较麻烦, 然后代码一定要优雅。。。 # include <iostream> # include <stdio.h> # include <algorithm> # include <time.h> # include <set> using namespace std ; typedef long long ll ; typedef double db ; typedef pair < int , int > piir ; struct Point { ll x , y ; bool operator < ( const Point k ) const { if ( x == k . x ) return y > k . y ; return x < k . x ; } Point operator - ( const Point k ) const { return ( Point ) { x - k . x , y - k . y } ; } bool operator == ( const Point k ) const {

2018icpc宁夏邀请赛网络赛_G_Trouble of Tyrant

◇◆丶佛笑我妖孽 提交于 2019-11-28 07:26:15
题意 一列 \(n\) 个点,给定一个特殊的图,有两种边 \(E(1,i)\) 和 \(E(i-1,i)\) ,多个询问,每次给一个 \(d\) ,求所有路径长度加上 \(d\) 后1到 \(n\) 的最短路。 分析 首先这图很特殊,大胆猜测不是图论。 1到 \(n\) 的最短路包括 \(p_i\) ,即1直接到 \(i\) 的距离, \(i\) 作为中转点,加上 \(dis_{i,n}\) ,即 \(i\) 一直往后走到 \(n\) 的距离,而该路径的边数就是 \(1+n-i\) ,因此对于每个询问 \(d\) ,该路径的长度就是 \(p_i+dis_{i,n}+d*(1+n-i)\) 。 因此转化为另一个问题,有 \(n\) 个二元组 \((a_i,b_i)\) ,对于每个 \(d\) ,求 \(min _{i=1}^{n}(a_i+d*b_i)\) 。 观察这个二元组的形式,可以再转化为一个几何问题,有 \(n\) 条直线,斜率为 \(b_i\) ,截距为 \(a_i\) ,对于每个询问的横坐标 \(d\) ,求最小的 \(y\) 值。 画个图观察,可以知道,我们所需要的就是这些直线下部的折线所围成的一个上凸包。 考虑用单调栈来维护,首先对直线按截距排序,枚举直线,如果斜率比上一条直线大,直接跳过,因为这条直线肯定在凸包的外部,没有贡献。

判断点是否在凸包内

浪子不回头ぞ 提交于 2019-11-28 01:14:30
周测5 描述 二维平面上,给定n个点{ai}和m个点{bi},且保证这n+m个点中,任意两个点的x坐标或y坐标均不相同。 对于每个bi,判断是否存在由3个ai,aj,ak(1≤i,j,k≤n,i≠j≠k)点组成的三角形包含bi(在三角形边上也算包含;允许三点共线的三角形,此时只有bi在三点中任意两点的线段上才算包含)。 输入 第一行为一个整数n。接下来n行,其中第i行有两个整数,表示ai的横纵坐标。 第一行为一个整数m。接下来m行,其中第i行有两个整数,表示bi的横纵坐标。 输出 输出m行,第i行为一个整数0或1,分别表示是否存在一个三角形包含该bi。 样例1输入 3 1 -6 -10 -1 0 6 3 -2 7 -4 -2 -3 1 样例1输出 0 1 1 样例1解释 如图,绿点为A,红点为B。2号、3号红点均包含于3个绿点里。 样例2 请查看下发文件内的sample2_input.txt和sample2_output.txt以及draw.py。 为了大家调试方便,我特意提供了一个draw.py的文件来绘制点集。大家需要安装python 3,然后 python3 -m pip install matplotlib 最后用 python3 draw.py 运行,将题中数据复制进去即可得到图片。(当然你也可以重定向数据) 限制 n,m≥3,坐标绝对值不超过 109 其中30%的数据

题解

别来无恙 提交于 2019-11-27 22:20:38
因为有些 ddl 要肝.. 把视频题解咕了..大家凑合着看文字题解吧 今年又是 Rikka 和 Yuta 在多校上秀恩爱的一年(说不定也是最后一年了.. sad 1001 Rikka with Quicksort 难度:medium 考察了大家对快速排序时间复杂度推导的熟悉程度(当然我是打表推式子的) 如果打表的话可以考虑下面这个式子,它是计算在 $m$ 处增加一个 $1$ 对答案的贡献。 $$ \begin{aligned} h_m(i) &= 0 & i < m\ h_m(i) &= 1 & i =m \ h_m(i) &= \frac{1}{i}\sum_{j=1}^{i}\left( h_m(j-1) + h_m(i-j)\right) & i > m \end{aligned} $$ 打表之后可以知道 $h_m(m)=1,h_m(n)=\frac{2(n+1)}{(m+1)(m+2)} (n > m)$。应该归纳一下就可以直接证明。所以把对应的贡献求和之后可以得到答案就是: $$ 2(n+1)H(n)-4n-\frac{2(m+2)H(m+1)-4(m+1)-m)(n+1)}{m+2} $$ 其中 $H(n)$ 表示调和级数。因为模数确定,可以用分段打表的策略来求调和级数的具体值:即把 $H(kS)$ 的值给打入程序中,这样每一次只需要计算 $kS+1$ 到 $n$

题解(临时)

爷,独闯天下 提交于 2019-11-27 22:19:36
因为有些 ddl 要肝 .. 把视频题解咕了 ..大家凑合着看文字题解吧 今年又是 Rikka 和 Yuta 在多校上秀恩爱的一年(说不定也是最后一年了 .. sad #### 1001 Rikka with Quicksort 难度: medium 考察了大家对快速排序时间复杂度推导的熟悉程度(当然我是打表推式子的) 如果打表的话可以考虑下面这个式子,它是计算在 $m$ 处增加一个 $1$ 对答案的贡献。 $$ \begin{aligned} h_m(i) &= 0 & i < m\\ h_m(i) &= 1 & i =m \\ h_m(i) &= \frac{1}{i}\sum_{j=1}^{i}\left( h_m(j-1) + h_m(i-j)\right) & i > m \end{aligned} $$ 打表之后可以知道 $h_m(m)=1,h_m(n)=\frac{2(n+1)}{(m+1)(m+2)} (n > m)$。应该归纳一下就可以直接证明。所以把对应的贡献求和之后可以得到答案就是: $$ 2(n+1)H(n)-4n-\frac{2(m+2)H(m+1)-4(m+1)-m)(n+1)}{m+2} $$ 其中 $H(n)$ 表示调和级数。因为模数确定,可以用分段打表的策略来求调和级数的具体值:即把 $H(kS)$ 的值给打入程序中,这样每一次只需要计算 $kS

二分,倍增的一些思考(浅谈二分)(lost my music:可持久化栈)

自古美人都是妖i 提交于 2019-11-27 16:32:42
来自8,17考试模拟24。 本题: 单调凸包。(找凸包方向:联系高考数学线性规划) 弹栈操作是一个个向后弹的。 序列转换为树上。 对于树上结构,只需记录父子关系,即可还原出一整棵树。 因为要可持久化,那么这里的栈也变为了树状。 只需记录在栈里的父亲即可。 甚至不用开一个数组作为栈。 由于单调性,搭配倍增使用,效果更佳。 二分,倍增的一些思考: 1、那么普通的数组类型栈由于单调性,且是序列上的连续,可以用二分和倍增快速pop (这里的二分指l,r,while循环,check(mid) 的二分) 2、既然既可以使用二分,也可以使用倍增,那他们的区别在哪儿? 发现:倍增是学lca时学到的,是用来解决树上问题。可以说他满足单调性,但由于树的特殊性质,无法用二分解决。 因此出现了倍增数组。良好地解决了树上二分祖先的问题。 推论:倍增数组也可以用在比树更简单的序列上。他是二分的强化版。 则二分能解决的问题倍增大多可以解决。 而大多情况下使用mid二分(也可倍增二进制拆分),是因为直接mid,不是固定log,可能会少一点。 而倍增i=20~0是二进制拆分,复杂度固定log,与二分上限相同,随机情况下会慢一点点。 不需要记录一些关系时,倍增的二进制拆分和二分是差不多的。 但是倍增数组提供了很多灵活而多样的功能,使他比单纯二分的适应性、功能性更强。 附:普通二分的倍增写法:( 相比麻烦一点 )(

矢量&凸包学习笔记

为君一笑 提交于 2019-11-27 08:39:01
矢量&凸包学习笔记 矢量 矢量(向量)的定义和表示法 定义:一条有方向的线段。 表示:如下图。 那么我们把这一条矢量写作: A B → \overrightarrow{AB} A B ,它的长度为 a a a ,记作 ∣ A B → ∣ \left|\overrightarrow{AB}\right| ∣ ∣ ∣ ​ A B ∣ ∣ ∣ ​ 。 矢量的运算 矢量的 加减 遵循 三角形法则 。 加: 根据三角形法则, ∣ A C → ∣ = ∣ A B → ∣ + ∣ B C → ∣ = a + b \left|\overrightarrow{AC}\right|=\left|\overrightarrow{AB}\right|+\left|\overrightarrow{BC}\right|=a+b ∣ ∣ ∣ ​ A C ∣ ∣ ∣ ​ = ∣ ∣ ∣ ​ A B ∣ ∣ ∣ ​ + ∣ ∣ ∣ ​ B C ∣ ∣ ∣ ​ = a + b 。 减: ∵ ∣ B C → ∣ = b \because \left|\overrightarrow{BC}\right|=b ∵ ∣ ∣ ∣ ​ B C ∣ ∣ ∣ ​ = b ∴ ∣ C B → ∣ ( ∣ B C ← ∣ ) = − b \therefore \left|\overrightarrow{CB}\right|(\left|