首页 > 其他分享 >【模板】WBLT

【模板】WBLT

时间:2024-01-31 17:55:06浏览次数:15  
标签:ch return val int siz pushdown WBLT 模板

todo:可持久化


#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stderr, ##__VA_ARGS__)
#else
#define debug(...) void(0)
#endif
typedef long long LL;
template <int N>
struct WBLT {
  static constexpr double alpha = 0.292;
  int ch[N << 1][2], val[N << 1], siz[N << 1], tot, root, tsh[N << 1], tct;
  WBLT() { root = newnode(-1e9); }
  bool isleaf(int p) { return !ch[p][0]; }
  void destroy(int p) { tsh[++tct] = p; }
  void maintain(int p) {  // also known as: pushup
    if (isleaf(p)) return ;
    val[p] = val[ch[p][1]];
    siz[p] = siz[ch[p][0]] + siz[ch[p][1]];
  }
  bool rev[N << 1];
  void spread(int p) {
    rev[p] ^= 1;
  }
  void pushdown(int p) {
    if (!rev[p] || isleaf(p)) return ;
    spread(ch[p][0]), spread(ch[p][1]);
    swap(ch[p][0], ch[p][1]);
    rev[p] = false;
  }
  void rotate(int p, int r) {
    if (isleaf(p) || isleaf(ch[p][r])) return ;
    int q = ch[p][r];
    pushdown(q);
    swap(ch[p][0], ch[p][1]);
    swap(ch[p][r], ch[q][r]);
    swap(ch[q][0], ch[q][1]);
    maintain(q);
    maintain(p);
  }
  void update(int p) {  // also known as: maintain
    if (isleaf(p)) return ;
    pushdown(p);
    int r = siz[ch[p][0]] < siz[ch[p][1]];
    if (siz[ch[p][!r]] >= siz[p] * alpha) return;
    pushdown(ch[p][r]);
    if (siz[ch[ch[p][r]][!r]] >= siz[ch[p][r]] * (1 - alpha * 2) / (1 - alpha))
      rotate(ch[p][r], !r);
    rotate(p, r);
  }
  int newnode(int v) {
    int p = tct ? tsh[tct--] : ++tot;
    val[p] = v;
    ch[p][0] = ch[p][1] = 0;
    siz[p] = 1;
    return p;
  }
  void insert(int p, int v) {
    if (isleaf(p)) {
      ch[p][0] = newnode(val[p]);
      ch[p][1] = newnode(v);
      if (val[ch[p][0]] > val[ch[p][1]]) swap(ch[p][0], ch[p][1]);
    } else {
      pushdown(p);
      insert(ch[p][val[ch[p][0]] < v], v);
    }
    maintain(p);
    update(p);
  }
  void erase(int p, int v) {
    pushdown(p);
    int r = val[ch[p][0]] < v;
    if (isleaf(ch[p][r])) {
      if (val[ch[p][r]] != v) return;
      destroy(ch[p][0]), destroy(ch[p][1]);
      int q = ch[p][!r];
      memcpy(ch[p], ch[q], sizeof ch[p]);
      val[p] = val[q];
      siz[p] = siz[q];
    } else {
      erase(ch[p][r], v);
    }
    maintain(p);
    update(p);
  }
  int getrnk(int p, int v) {
    int res = 0;
    while (!isleaf(p)) {
      pushdown(p);
      int r = val[ch[p][0]] < v;
      if (r) res += siz[ch[p][0]];
      p = ch[p][r];
    }
    return res + (val[p] < v);
  }
  int getkth(int p, int k) {
    k += 1;
    while (!isleaf(p)) {
      pushdown(p);
      int r = k > siz[ch[p][0]];
      if (r) k -= siz[ch[p][0]];
      p = ch[p][r];
    }
    return val[p];
  }
  int merge(int p, int q) {
    if (!p || !q) return p + q;
    if (min(siz[p], siz[q]) >= alpha * (siz[p] + siz[q])) {
      int t = newnode(0);
      ch[t][0] = p, ch[t][1] = q;
      maintain(t);
      return t;
    }
    if (siz[p] >= siz[q]) {
      pushdown(p);
      if (siz[ch[p][0]] >= alpha * (siz[p] + siz[q])) {
        ch[p][1] = merge(ch[p][1], q);
      } else {
        pushdown(ch[p][1]);
        ch[p][0] = merge(ch[p][0], ch[ch[p][1]][0]);
        ch[p][1] = merge(ch[ch[p][1]][1], q);
      }
      maintain(p);
      return p;
    } else {
      pushdown(q);
      if (siz[ch[q][1]] >= alpha * (siz[p] + siz[q])) {
        ch[q][0] = merge(p, ch[q][0]);
      } else {
        pushdown(ch[q][0]);
        ch[q][1] = merge(ch[ch[q][0]][1], ch[q][1]);
        ch[q][0] = merge(p, ch[ch[q][0]][0]);
      }
      maintain(q);
      return q;
    }
  }
  void split(int p, int k, int &x, int &y) {
    if (!k) return x = 0, y = p, void();
    if (isleaf(p)) return x = p, y = 0, void();
    pushdown(p);
    if (k <= siz[ch[p][0]]) {
      split(ch[p][0], k, x, y);
      y = merge(y, ch[p][1]);
    } else {
      split(ch[p][1], k - siz[ch[p][0]], x, y);
      x = merge(ch[p][0], x);
    }
    destroy(p);
  }
  void dfs(int p) {
    pushdown(p);
    if (isleaf(p)) {
      if (val[p] > 0) cout << val[p] << " ";
      else debug("-inf ");
    } else {
      dfs(ch[p][0]);
      dfs(ch[p][1]);
    }
  }
  void print(int p) {
    if (!isleaf(p)) print(ch[p][0]),print( ch[p][1]);
    debug("ch[%d] = {%d, %d}\n", p, ch[p][0], ch[p][1]);
  }
};
WBLT<300010> t;
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) t.insert(t.root, i);
  for (int i = 1; i <= m; i++) {
    int l, r;
    cin >> l >> r;
    debug("l = %d, r = %d\n", l, r);
    int x, y, z;
    t.split(t.root, l, x, y);
    t.split(y, r - l + 1, y, z);
    t.spread(y);
    t.root = t.merge(x, t.merge(y, z));
  }
  t.dfs(t.root), cout << endl;
  return 0;
}

标签:ch,return,val,int,siz,pushdown,WBLT,模板
From: https://www.cnblogs.com/caijianhong/p/17999815/template-wblt

相关文章

  • [职场] 就业推荐表个人简历模板范文
    就业推荐表个人简历篇1姓名:张大大目前所在:广州年龄:21户口所在:广东省国籍:中国婚姻状况:民族:汉族求职意向人才类型:普通求职应聘职位:财务/会计助理/会计文员工作年限:0职称:无职称求职类型:实习可到职日期:随时......
  • 算法模板 v1.6.1.20240131
    算法模板v1.1.1.20240115:之前的历史版本已经不可寻,创建了第一份算法模板。v1.2.1.20240116:删除“编译”-“手动开栈”与“编译”-“手动开O优化”;将“编译”-“CF模板”中的第20行代码cin>>T;注释;删除“读写”及其目录下的内容;删除“图论”-“欧拉图”-“混合图”;删除“图论”-......
  • 空白模板
    前言  本模版使用TinyMCE5进行编辑,以后写博客可以复用此模板,方便自己排版博客和发博客1.标题一  内容,内容importtorchdefcheck_cuda_availability():iftorch.cuda.is_available():device=torch.cuda.current_device()print("CUDAisavaila......
  • 无涯教程-ExpressJS - 模板(Templating)
    Pug是Express的模板引擎,Pug是一个非常强大的模板引擎,具有多种函数,包括filter,includes,inheritance,interpolation等。要将Pug与Express一起使用,无涯教程需要安装它。npminstall--savepug现在已经安装了Pug,将其设置为您的应用程序的模板引擎。将以下代码添加到您的index.js文......
  • 7.模板Template
    WPF的模板基类叫FrameworkTemplate,它是一个抽象类,它有三个子类,分别是ControlTemplate(控件模板)、ItemsPanelTemplate(元素面板模板)和DataTemplate(数据模板)ControlTemplate控件模板用于定义控件的外观,也就是Control基类的Template属性,而绝大多数控件都继承于Control基类,意味着我们......
  • 算法模板 v1.5.1.20240130
    算法模板v1.1.1.20240115:之前的历史版本已经不可寻,创建了第一份算法模板。v1.2.1.20240116:删除“编译”-“手动开栈”与“编译”-“手动开O优化”;将“编译”-“CF模板”中的第20行代码cin>>T;注释;删除“读写”及其目录下的内容;删除“图论”-“欧拉图”-“混合图”;删除“图论”-......
  • P8306 【模板】字典树
    P8306【模板】字典树字典树树简介字典树英文名为\(Trie\)树,就是像字典一样的树。字典树树正文我们建一棵树,边表示字母和数字,节点表示根到此节点的字符串,假设有某个点,其子节点表示在这个字符串上再加一个字母的字符串。那么这样如何解决这道题呢?首先我们要根据题目给定的......
  • 算法模板 v1.4.2.20240129
    算法模板v1.1.1.20240115:之前的历史版本已经不可寻,创建了第一份算法模板。v1.2.1.20240116:删除“编译”-“手动开栈”与“编译”-“手动开O优化”;将“编译”-“CF模板”中的第20行代码cin>>T;注释;删除“读写”及其目录下的内容;删除“图论”-“欧拉图”-“混合图”;删除“图论”-......
  • Prometheus 主机监控管理模板
    systemd管理node_exporterhttps://prometheus.io/download/#node_exporterwgethttps://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz~]#tar-xfnode_exporter-1.7.0.linux-amd64.tar.gznode_exporter-1.7.......
  • C++类模板
    1.类模板作用:建立一个通用类,类中的成员数据类型可以不具体制定,用一个虚拟的类型来代表语法:template<typenameT>类解释:template-声明创造模板typename-表面其后面的符号是一种数据类型,可以用class代替T-通用的数据类型,名称可以替换,通常为大写字母二.类模板和函数模......