线段树分裂


线段树合并

线段树合并板子


线段树分裂

将以 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) \]

用线段树合并解决。

记录

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