2019暑期金華集訓 Day6 計算幾何

2022-05-08 00:00:15 字數 3345 閱讀 1993

內積不等式:

\[(a,b)^2\le (a,a)(b,b)

\]其中\((a,b)\)表示\(a\cdot b\)。

(好像是廢話?)

\[a\times b=|a||b|\sin \theta

\]二維叉積:\(a\times b=x_1y_2-x_2y_1\)。

三維叉積:

\[a\times b=\left|

\begin

i&j&k\\

ax&ay&az\\

bx&by&bz

\end

\right|

\]叉積判直線關係:??

atan2(y,x),返回值\((-\pi,\pi]\)。

如果極角相差較大可以用這個來判,否則由於精度問題可能要用叉積。在值域\(10^9\)的時候這個函式可能基本沒用。

向量的旋轉,直接用三角函式公式推一推即可,可以寫成矩陣的形式。

每時刻有旋轉/平移/縮放等操作,問乙個向量在\([l,r]\)中操作之後會變成什麼。

直接寫成矩陣乘法的形式,用線段樹維護。

對於二次函式\(f(x)\),有

\[\int_^r f(x)\mathrm dx=\frac

\]對於其他函式,可以用二次函式擬合。

求\(p\)在直線\(p_1p_2\)上的投影點/對稱點。

直接把直線\(p_1p_2\)的垂線做出來,求個交,就沒了。

也可以用點積得到\(pp_1\)在\(p_1p_2\)上的投影長度,然後也可以求出垂足。

直接點積叉積亂搞一通就沒了。

直線的位置關係、線段的位置關係都差不多。

先把直線平行、直線重合判掉。

然後分別把兩條線段的端點取出來,看是否在另一條直線的兩邊。

(老師給的方法:先判外接矩形是否相交,然後再做跨立實驗)

把直線重合判掉,然後當成直線來求交點。

距離定義為最近點對的距離。

如果有交點則為0,否則變成點到線段距離。

點到線段距離?點積判一下端點之間位置關係然後直接做。

不保證多邊形是凸的。

直接在二維平面上隨便選乙個點然後叉積。

直接叉積就沒了。

射線法大家都知道,但有很多噁心的邊界情況。

兩種方法:

第一種:把斜率設成乙個奇怪的無理數,多半可以跳過所有邊界情況。

第二種:欽定射線向右,把所有邊界情況都判了就完事了。

邊界:如果射線與邊重合那麼continue

如果穿過了\(ab\)的\(a\),而且\(ab\)向下,那麼計數器++。

如果穿過了\(ab\)的\(b\),而且\(ab\)向上,那麼計數器++。

如果點在邊上那麼直接返回。

大家都會?

旋轉卡殼。

把有關的點摳出來,仍然是乙個凸包,然後算面積即可。

k-d tree多好

分治,然後發現左邊匹配右邊只會有\(o(1)\)個點有可能產生貢獻,於是沒了。

相離,外切,相交,內切,內含。

圓心和半徑的關係亂搞即可。

知道半徑、知道圓心到直線的距離,於是可以得到弦長,於是沒了。

可以求出交點的直線方程,於是沒了。

當然,也可以用餘弦定理解三角形得到答案。

知道半徑、知道距離、知道有乙個直角,於是可以解三角形。

首先判掉內含、內切。

此時必然有兩條外公切線,解一解三角形。

內公切線類似。

可以通過有向面積化成三角形和圓的交的面積。注意到三角剖分的原點任意,可以設為圓心。

如果三個點都在裡面那麼很容易。

否則就把線段\(ab\)與圓的交點搞出來,把三角形切開,遞迴搞。

只會遞迴常數層,但比較好寫。

直接暴力,對於每個圓盤求出後面的圓盤蓋掉它的角度區間,求個區間並就沒了。

角度區間可以求圓的交點來求。

設\(dp_x\)表示從\(x\)跳到某個葉子的最小代價,從下往上dp。

每次求\(x\)的答案的時候發現就是乙個斜率優化,啟發式合併把子樹內的凸包合起來就沒了。

dsu on tree維護凸包也可以。

然後就是要支援往凸包裡插入乙個點,拿set亂搞即可。

發現最多選4個向量,而且選4個向量的時候只能是互相垂直的,可以判掉。於是只要選3個向量,使得相鄰兩個向量的夾角小於180。

然後把所有向量反向再加進去,正向的設為紅色,反向的設為綠色。

於是我們就要找形如「紅綠紅」的三條向量,並且兩個紅向量的夾角小於180。

列舉第乙個紅向量,資料結構維護後面兩個的最小值。

結論:三角形不相交等價於能做出兩條內公切線。

然後列舉一條公切線,答案就是公切線兩邊分別選兩個點的方案數。

圓反演,點在圓內轉化為點在直線的某一側。

於是變成動態半平面交,也許可以轉化為凸包做?

對於乙個點\(p\),如果\(p\)對\(o\)反演,那麼\(p\)仍然在射線\(op\)上,距離變為原來的倒數。

一條不過\(o\)的直線反演後變成乙個過\(o\)的圓,反之亦然。

不過\(o\)的圓反演後仍然是不過\(o\)的圓。

圓反演,就變成了求兩個圓的某個特定公切線。(注意原題需要外切,所以不能亂搞公切線)

注意「不相交」也保證了兩個多邊形不能相互包含。

考慮射線法,看乙個點往上對著的第乙個線段,如果是從右往左那麼就在多邊形外,否則在多邊形內。(假設邊是按順時針走的)

如果可以離線,那麼按\(x\)排序一下從左往右搞,因為沒有相交的邊,所以用set很好維護。

不能離線,那麼用可持久化treap維護。

細節很多,也許旋轉某個無理數角度會有點用?

樹剖,把樹上的問題轉化為序列上的問題。

以時間為\(x\)軸、位置\(y\)軸,那麼一次位移就是二維平面的一條線段。

問題就轉化為\(m\log n\)條線段什麼時候最早相交。

按\(x\)座標掃瞄線,用\(set\)維護所有線段的\(y\)的相對大小關係。

如果兩條線段有交,那麼他們一定會有某個時刻在set裡是相鄰的。

又因為我們只需要求最早的交點,所以我們可以認為set裡面的線段永遠不相交,因為當我們跑到相交的時間的時候就要直接返回答案了。

於是每次加入一條線段的時候判一下和前驅後繼相交的時間,更新一下結束時間。如果當前時間超出了結束時間那麼就可以直接返回了。

設\(f(x)\)表示極角為\(x\)的射線左邊面積減去右邊面積,那麼有\(f(0)=-f(\pi)\)。

所以中間必然存在零點,可以二分這個零點。

考慮二分了乙個極角之後怎麼求\(f(x)\)。可以使用二分得到這條射線與凸包的各種交點,然後用各種字首和得到面積,所以可以\(o(\log n)\)得到\(f(x)\)。

所以我們\(o(n\log^2 n)\)做出了答案。

(聽起來細節就特別特別多……)

2019暑期金華集訓 Day7 動態規劃

首先發現這個樹的形態沒啥用,只需要保證度數之和是 2n 2 且度數大於0即可。然後設 dp 表示前 i 個點用了 j 個度數的最小值,然後就獲得了 o n 3 的dp。不妨每個點的度數都減1,那麼總度數就變成 n 2 了。考慮原來 i 的作用是什麼 要限制選的點數不能超過 n 此時我們總度數小於 n...

2019暑期金華集訓 Day1 組合計數

n le 10 直接暴力列舉。n le 32 meet in the middle,如果左邊選了 x 右邊選了 y 且 x y le b 那麼對答案的貢獻就是 根據範德蒙德恒等式 sum n 所以上面可以拆開成 sum 列舉 x 關於 y 是乙個字首和。如果沒有下界的限制,只有 p i in 0,r...

2019暑期金華集訓 Day3 字串

考慮字尾樹。sam的parent樹是反串的字尾樹,所以後面加乙個字元的時候相當於往串前面加乙個字元,恰好多出了乙個字尾。於是可以以此來理解sam。每一條路徑對應原串的乙個子串。每乙個終止節點對應一些字尾。所有到同乙個點的路徑對應的子串互為字尾,長度連續。parent樹是反串的字尾樹。sam可以用來構...