基礎資料結構

9/23 校隊培訓

FHVirus

前言

  • 本篇是基礎的資料結構
    前半為 APCS 範圍,後半為競程常用
  • 健康使用資結
    請先想清楚自己需要什麼操作
    再針對這些操作做出最精簡的資結
    不要看到區間就砸線段樹
  • 實作注意
    請先想清楚需要什麼功能再開刻
    尤其是線段樹

Deque 例題

給定一個長度為 \(N \le 10 ^ 6\) 的整數序列 \(a\) 及整數\(k\)  ,

對於所有 \(i\) 求 \(max_{j = max(1, i-k)} ^ {i-1} {a_j}\)  

Binary tree & Cartesian tree

我不確定後者中文是什麼

Binary tree

Binary tree

  • 一棵樹
  • 每個節點有最多兩個小孩

Cartesian Tree

Catersian Tree

  • 一棵對應到序列的二元樹
  • 根是最小值
  • 每個節點 \(u\) 左(右)子節點都是
    \(u\) 左(右)邊比 \(a_u\) 大的最小值
  • 不存在的話就沒有子節點

Building Catersian Tree

  • Naive \(O(n ^ 2)\)
  • 耍毒瘤 \(O(n \log n)\)
  • \(O(n)\) ?

對不起我用了線段樹

APCS 到此為止。

應該沒有漏吧。休息一下。

線段樹

為什麼這邊用中文叫線段樹?

實際上有另一個真的用來存線段的樹(資料結構)
英文也叫 Segment Tree

出了競程圈記得有這個資結

何謂線段樹?

  • 一棵維護序列的二元樹
  • 分治
    把序列對半切,試著從子節點的資訊維護自身資訊

線段樹精神

  • 任意區間分拆乘固定 \(O(\log n)\) 個區間
    且節點數、邊數皆 \(O(n)\)
    不一定要用在資結上
  • 本質是分治+紀錄
    跟 DP 是差不多的
    在合併子節點的時候要想清楚

實作小技巧

// map segment [l, r] to an 
// distict interger id(l, r)
inline int id(int l, int r){
    return (l + r) | (l != r);
}

這樣空間只要開 \(2n\)
證明在右方連結滑到 7/20 的地方。

BIT 精神

  • 線段樹減肥
    任意前綴區間分拆成 \(O(\log n)\) 個區間
  • 前綴性質
    像前綴一樣好好推式子

BIT 挑戰題

給你一個長度為 \(N \le 10^5\) 的序列,支援以下操作

  • 區間加值
  • 求區間和

你能用 BIT 做到嗎?

Made with Slides.com