2018年3月1日

[程式] 不用除法的最大公因數 (GCD)

有不少數論 (Number Theory) 的計算中都會用到找兩個正整數的最大公因數 (greatest common divisor, GCD),而最基本常用找最大公因數的方法中就是利用輾轉相除法 (Euclidean algorithm),如下
$gcd(x, y) = gcd(y, x - q \times y)$
其中 q 為任意整數,下面的這段程式實作出輾轉相除法的概念:
int gcd(int x, int y)
{
 while ((x %= y) && (y %= x)) ;
 return (x + y);
}
然而,在現在處理器中求餘數的運算時間相較於基本的加減法以及位元運算 (bitwise operation) 是慢很多的,因此 Knuth 的 TAOCP (The Art of Computer Programming) 中的第 4.5.2 節就有提到其實曾經有人提出了另一種方法,僅僅使用位元運算以及加減法來找最大公因數。

2018年2月24日

[程式] 最近共同祖先 (Lowest Common Ancestor - LCA)

LCA 算是 tree 滿容易用上的一項特性,原因在於找出任意兩點 u, v 的 LCA 後 (假設是 w),通常問題可以拆解為:
  • (u -> w) + (v -> w): 這樣的兩條路徑各自求解後合併
LCA 的找法可以參考演算法筆記中的 Jump Pointer Algorithm,他的基本概念就是對每個 node 的前 1、2、4、8 ... (2^n) 倍的祖先,如此一來,假設要知道一個 node 的前 5 代祖先是誰,只要知道他的前一代祖先的前四代祖先是誰就可以了。(簡單來說,看成用二進位表示法就知道這種儲存方式可以得知任意一個點的任意一代的祖先囉)

透過這種方法,對任意 2 點 u, v,我們可以知道最後的共同的祖先必然是 root,從上往下追蹤直到出現分歧為止,這就是最近的共同祖先拉。

2018年2月18日

[程式] Segment Tree (線段樹)

Segment Tree 是個用空間來交換時間的資料結構,特別適合用在搜尋次數極為龐大的時候。其所需的額外空間約為既有資料的兩倍 (空間複雜度是 O(N)!),時間複雜度則為 O(log(N))。

2018年2月8日

[筆記] Codeforces 920E: Connected Components?

[題意] 給一個有 n 個點的 undirected simple graph,並且告訴你這個 graph 中有 m 條邊被拿掉了,問有幾個 connected components?並且把 connected component 的大小由小到大印出來。

2018年2月7日

[程式] 排容原理實作 (inclusion-exclusion principle implementation)

由於先前這一篇會用到排容原理,因此就花了點時間研究排容原理要怎麼實作比較好。不過這玩意兒因為只是個原則,實作方法會根據要處理的問題有些許差別,這邊的實作針對的是以下的問題:

給定兩個正整數 $n$ 跟 $x$,要找出有多少正整數 $y$ 使得 $y < n \ \& \ gcd(y, x) = 1$,其中 $gcd$ 代表最大公因數

[筆記] Codeforces 920G: List Of Integers

[題意] 給定任意正整數 p, 則 L 是一串與 p 互質的序列 L(p) = {y | gcd(y, p) = 1},且 L 是由小到大排序的 (gcd 就是最大公因數)。再給任一正整數 x,求 L 中比 x 大的第 k 個數值。

2018年2月2日

[隨筆] 第一場博士論文口試 (校內口試)

歷經各種狀況後,原定計畫是去年 9 月就能口試,結果各種投稿不順利就一路的延到現在終於可以口試了,算一算差了大約快半年 Orz 在這期間還發現系上對於博士口試還非常囉嗦,各種資格審查 & 行政文件要跑...雖然正式的口試還沒開始,不過就先記錄一下今天的前哨戰:校內口試吧

2018年1月6日

[筆記] 頂級勃根地紅酒的敲門磚

如果要問我這次的品飲的心得,我認為可以用下面的問句做個總結:
當你拿到了前往山頂的敲門磚,你也從眾多文章中得知了山頂有著曼妙絕倫的風景,只是通往山頂的路途漫漫,考驗極多,代價高昂,要看到預期中的風景還得要運氣好,那麼...你是否還願意攻頂?

2017年10月15日

[筆記] Social Psychology: Heuristic (思考經驗法則)

思考經驗法則簡單來說就是根據 "經驗" 來做判斷,即便這個經驗所推論出的結論是錯的,但經驗法則的特點在於這會是第一時間最容易浮現腦海中並影響我們判斷的準則

2017年10月9日

[C++] covariance / contravariance

covariance / contravariance 是跟繼承有密切關聯的產物,而且與語言規範有關。然而這邊雖然要講這兩項性質,實際上 C++ 的語言規範上是 invariance,因此若要達到類似效果,在 C++ 必須要在類別設計時就加以考量。

 covariance / contravariance 簡單來說,就是在特性情況下,子型別與父型別之間能否接受互相轉換。這個特定情況舉例來說,就是放在 container 內的狀況。