語法書 / AA 競程語法書 下冊 / 第十七單元 / 優化,是在優化什麼?

17.1 優化,是在優化什麼?

先把 10.1 的結論搬回來:程式會不會 TLE,由「運算次數隨資料量 n 成長的形狀」決定——認出 O、代入最大的 n、除以 10^9 跟時限比。

所以優化的目標是換形狀,不是修零頭。一個 O(n^2) 的做法在 n = 10^5 要跑 10^{10} 次,就算你把迴圈裡的運算精簡一半,也還有 5 \times 10^9 次——照樣 TLE。真正的出路是把形狀往下換一階:

n = 10^{12} 運算次數 感受
O(n) 10^{12} 約一千秒,死當
O(\sqrt{n}) 10^6 眨眼
O(\log n) 40 快到測不出來
O(1) 1 一步

同一個 n,形狀差一階就是天堂與地獄。本單元的五個例子,每一個都是一次「換形狀」:

  1. 用數學性質——把整段迴圈換成一條公式(17.2)
  2. 用陣列儲存資訊——把「每次都重找」換成「查表一步」:mex 函數(17.3)
  3. 因數成對——把試除範圍砍到 \sqrt{n}:質數判斷(17.4)
  4. 每輪減半——把逐一刪除換成整輪重建:約瑟夫問題(17.5)
  5. 一直除以 2改變枚舉順序——認識 \log:Odd Divisor 與 A*B*C(17.6、17.7)