線段樹分裂


線段樹合併

線段樹合併板子


線段樹分裂

將以 x 爲根的線段樹分裂成 x,y 爲根的兩顆線段樹, 前 k 小在 x, 之後的在 y。

void split (int x, int & y, int k) {
  y = newnode();
  int v = val[ch[x][0]];
  if (k > v)
    split (ch[x][1], ch[y][1], k - v);
 	else {
    swap (ch[x][1], ch[y][1]);
    if (k < v)
      split (ch[x][0], ch[y][0], k);
  }
  val[y] = val[x] - k;
  val[x] = k;
}

板子記錄


HEOI2016/TJOI2016 排序

線段樹合併/分裂解決區間排序問題。

某種維護區間染色的方法(類似 Old Driver Tree)

// 使用 set 維護數列 1~n
// 區間 [l,r] 只在 set 保留 l
// n + 1 作爲哨兵
for (int i = 1; i <= n + 1; ++ i)
  set.insert (i);

// split (i) 操作, 操作後保證 i 是某個區間的開頭, 
iterator split (int p) {
  iterator i = lower_bound (p);
  if (*i == p) return i;
  // 在這裏進行某些操作來維護區間
  return set.insert (p).first;
}

// 把區間 [l,r] 染色
void gao (int l, int r) {
  iterator il = split (l), ir = split (r + 1);
  // 在這裏進行某些操作來維護區間
  t.erase (++ il, ir);
}

記錄


PKUWC2018 Minimax

\(f(u,i)\) 爲節點 \(u\) 是第 \(i\) 小的概率。

\[f(u,i)=\\ f(ls[u],i)*\left(p_u\sum_{j=1}^{i-1}f(rs[u],j)+(1-p_u)\sum_{j=i+1}^mf(rs[u],j)\right) \\ + \\ f(rs[u],i)*\left(p_u\sum_{j=1}^{i-1}f(ls[u],j)+(1-p_u)\sum_{j=i+1}^mf(ls[u],j)\right) \]

用線段樹合併解決。

記錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章