###### tags: `HW` --- slideOptions: transition: slide --- # DSA HW2 演習課 --- ## 目錄 1. 輸出入優化 2. 廢話 3. Lowest Common Ancestor 4. 另一種二分搜 5. 零碎 6. 延伸閱讀 --- ## 輸出入優化 ---- ios_base::sync_with_stdio(0); cin.tie(0); [chino](http://chino.taipei/note-2016-0311C-%E7%9A%84%E8%BC%B8%E5%87%BA%E5%85%A5cin-cout%E5%92%8Cscanf-printf%E8%AA%B0%E6%AF%94%E8%BC%83%E5%BF%AB%EF%BC%9F/) ( 推薦閱讀指數 : 2/5 ) ---- ### 結論 如果要用cin/cout, 1. 加上輸出入優化 2. 用'\n' 而非endl 3. 不要使用scanf/printf ---- 如果要用printf/scanf, 1. 不要加上輸出入優化 2. 如果混用cin/cout還是可能變慢 ---- Note : 1. cin/cout加了輸出入優化後,孰優孰劣見仁見智 2. cin/cout較慢,不是因為需要判斷型別。 (型別判斷在編譯時就做了) --- ## 廢話 ---- ### 父節點(父親) 往上走一格 ---- ### 子節點(兒子) 你是你父親的兒子 ---- ### 祖先 自己和往上可以走到的點 (自己和父親和父親的祖先) ---- ### 深度 你跟根的距離 --- ### Lowest Common Ancestor (LCA) Definition : 最低的 共同的 祖先 [DJWS](http://www.csie.ntnu.edu.tw/~u91029/Tree.html#5) ( 推薦閱讀指數 : 3/5 ) ---- 祖先們 : root CA CA CA LCA A $\ ~$a A $\ \ \ ~$ a A $\ \ \ \ \ ~$ a A $\ \ \ \ \ \ \ ~$ a $\ \ ~$ 我 $\ \ \ \ ~$ 不是我 ---- #### Jump Pointer Algorithm 中文俗稱倍增法 中心思想 : 如果$(a,b)$的LCA是在$x$節點,那麼以$x$為分界, 在所有 $a,~b$ 的祖先中,若是$x$的祖先, 必為共同祖先,反之必不為 ---- 所以是否為祖先具有單調性(可二分搜的性質) ---- 但是我要怎麼找到第$k$輩的祖先? ---- 維護所有節點的$2^i$輩祖先 維護方法:已知所有節點的$2^0$輩祖先 而一旦有了$2^i$輩祖先,易知$2^{i+1}$輩祖先 ---- 但是我要怎麼知道第$k$輩的祖先是不是CA? ---- 先把深度深的跳到跟淺的一樣深 $(a,b)$同時跳,看看是否跳到同一個點 ---- 這樣就可以AC了(吧? --- ### 另一種二分搜 ###### (通常都是這樣做) ---- 剛剛那種二分搜的方式是$O(log^2~n)$ ---- 我們有$log^2$ 是因為我們二分搜深度 再用$log$個數字湊出一個深度 <span>這兩件事,某種意義上可以合併(?<!-- .element: class="fragment" data-fragment-index="1" --></span> ---- 假設最終要跳到的點$x$ 跟現在深度相差$d$ 二進位表示是$10110$ ---- $10110$ <span>先看看最高位<!-- .element: class="fragment" data-fragment-index="1" --></span> <span>$10000$ : 非CA(因此會跳)<!-- .element: class="fragment" data-fragment-index="2" --></span> <span>再看看次高位<!-- .element: class="fragment" data-fragment-index="3" --></span> <span>$11000$ : 是CA(因此不跳)<!-- .element: class="fragment" data-fragment-index="4" --></span> <span>.<!-- .element: class="fragment" data-fragment-index="5" --></span> <span>.<!-- .element: class="fragment" data-fragment-index="5" --></span> <span>.<!-- .element: class="fragment" data-fragment-index="5" --></span> ---- 最後會跳到哪 ? ---- root CA CA CA LCA A $\ ~$a <span><!-- .element: class="fragment highlight-red" data-fragment-index="0" -->A</span> $\ \ \ ~$ <span><!-- .element: class="fragment highlight-red" data-fragment-index="0" -->a</span> N $\ \ \ \ \ ~$ N N $\ \ \ \ \ \ \ ~$ N ---- root CA CA CA <span><!-- .element: class="fragment highlight-green" data-fragment-index="0" -->LCA</span> A $\ ~$N A $\ \ \ ~$ N A $\ \ \ \ \ ~$ N <span><!-- .element: class="fragment highlight-green" data-fragment-index="0" -->A</span> $\ \ \ \ \ \ \ ~$ N ---- 所以需要特判!! --- ### 零碎 ---- 把根的父親設為自己 ---- 二分搜上限直接設$\lceil log(N) \rceil$ --- ### 延伸閱讀 ---- [用樹上歐拉路徑做LCA](https://tioj.ck.tp.edu.tw/uploads/attachment/11/54/7.pdf?fbclid=IwAR17Z3VOAf9nXygghEkx8kYw_tKBsQk3YNe2FvPNM9AyRjXDIYOlQzNLeWY)(made by 塗大為) [Sparse table](https://tioj.ck.tp.edu.tw/uploads/attachment/5/28/6.pdf)(made by 吳聖福) ( 推薦閱讀指數 : 4/5 )
{"metaMigratedAt":"2023-06-14T20:44:49.084Z","metaMigratedFrom":"Content","title":"DSA HW2 演習課","breaks":true,"contributors":"[{\"id\":\"565a52da-4ded-4359-a9ad-9490adc123bb\",\"add\":3714,\"del\":633}]"}
    1465 views