写小作业的时候重新复习了一下splay

只支持插入,删除,查k大,查节点数。没有迭代器。

T类型需要重载==和<,要调用拷贝构造函数。

template<class T>
class Splay {
private:
struct node {
T v;
node *ch[2], *fa;
int size;
node(const T &a) : size(1), v(a), ch{nullptr, nullptr}, fa(nullptr) {};
void setc(node *r, int c) {
ch[c] = r;
if (r != nullptr) r->fa = this;
}
int pl() {
if (fa != nullptr) return fa->ch[1] == this;
else return 0;
}
void count() {
size = 1;
if (ch[0] != nullptr) size += ch[0]->size;
if (ch[1] != nullptr) size += ch[1]->size;
}
};
node *root; void release(node *r) {
if (r == nullptr) return;
release(r->ch[0]);
release(r->ch[1]);
delete r;
} public:
Splay() : root(nullptr) {} ~Splay() {
release(root);
} private:
void rotate(node *r) {
node *f = r->fa;
int c = r->pl();
if (f == root) r->fa = nullptr, root = r;
else f->fa->setc(r, f->pl());
f->setc(r->ch[c ^ 1], c);
r->setc(f, c ^ 1);
f->count();
} void splay(node *r, node *tar = nullptr) {
for(; r->fa != tar; rotate(r))
if (r->fa->fa != tar) rotate(r->fa->pl() == r->pl() ? r->fa : r);
r->count();
} void rm(node *); public:
int size(); void remove(const T &); void insert(const T &); T *kth(int);
}; template<class T>
int Splay<T>::size() {
if (root == nullptr) return 0;
else return root->size;
} template<class T>
void Splay<T>::rm(node *r) {
node *f = nullptr;
if (r->ch[0] == nullptr && r->ch[1] == nullptr) {
if (r == root) root = nullptr;
else {
f = r->fa;
r->fa->setc(nullptr, r->pl());
delete r;
}
} else if (r->ch[0] == nullptr || r->ch[1] == nullptr) {
int c = r->ch[0] == nullptr;
node *t = r->ch[c];
while (t->ch[c ^ 1] != nullptr) t = t->ch[c ^ 1];
splay(t, r->fa);
r->fa->setc(nullptr, c ^ 1);
f = r->fa;
delete r;
} else {
node *h = r->ch[0], *t = r->ch[1];
while (h->ch[1] != nullptr)
h = h->ch[1];
while (t->ch[0] != nullptr) t = t->ch[0];
splay(h, r->fa);
splay(t, h);
t->setc(nullptr, 0);
delete r;
f = t;
} while (f != nullptr) {
f->count();
f = f->fa;
}
} template<class T>
void Splay<T>::remove(const T &a) {
node *r = root;
while (r != nullptr) {
if (r->v == a) {rm(r); break;}
if (a < r->v) r = r->ch[0];
else r = r->ch[1];
}
} template<class T>
void Splay<T>::insert(const T &a) {
node *r = root;
node *n = new node(a);
if (root == nullptr) {
root = n;
return;
}
while (r != nullptr) {
if (r->v == a) {delete n; break;}
if (a < r->v) {
if (r->ch[0] == nullptr) {
r->setc(n, 0);
splay(n);
break;
}
else
r = r->ch[0];
} else {
if (r->ch[1] == nullptr) {
r->setc(n, 1);
splay(n);
break;
}
else
r = r->ch[1];
}
}
} template<class T>
T *Splay<T>::kth(int k) {
node *r = root;
while (r != nullptr) {
int l_size = 0;
if (r->ch[0] != nullptr) l_size = r->ch[0]->size;
if (l_size >= k) r = r->ch[0];
else if (l_size + 1 == k) return &r->v;
else {
k -= (l_size + 1);
r = r->ch[1];
}
}
return nullptr;
}

【Naive Splay Template】的更多相关文章

  1. 【private HibernateTemplate template;】 的作用

    [private HibernateTemplate template;] 的作用 这个是在spring中定义了一个bean,它是org.springframework.orm.hibernate3. ...

  2. DiscuzX2.5,X3.0,X3.1,X3.2完整目录结构【模板目录template】

    /template/default/common  公共模板目录全局加载 block_forumtree.htm  DIY论坛树形列表模块 block_thread.htm  DIY帖子模块调用文件 ...

  3. [luogu3380][bzoj3196]【模板】二逼平衡树【树套树】

    题目地址 [洛谷传送门] 题目大意 区间查询k的排名,查找k排名的数,单点修改,区间前驱,区间后继. 感想 真的第一次写树套树,整个人都不对了.重构代码2次,发现样例都过不了,splay直接爆炸,可能 ...

  4. 【机器学习Machine Learning】资料大全

    昨天总结了深度学习的资料,今天把机器学习的资料也总结一下(友情提示:有些网站需要"科学上网"^_^) 推荐几本好书: 1.Pattern Recognition and Machi ...

  5. 【白话设计模式四】单例模式(Singleton)

    转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...

  6. Python之路【第二十篇】其他WEB框架

    WEB框架功能分析 WEB框架本质上,就是一个SOCKET Server WEB框架前面有WSGI或者是自己写的SOCKET,然后交给URL路由系统处理,然后交给某个函数或某个类,然后在模板里拿到模板 ...

  7. Python之路【第十七篇】:Django【进阶篇 】

    Python之路[第十七篇]:Django[进阶篇 ]   Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...

  8. 【面试题021】包含min函数的栈

    [面试题021]包含min函数的栈  MinStack.cpp: 1234567891011121314151617181920212223242526272829303132333435363738 ...

  9. 【单页应用】view与model相关梳理(转载)

    [单页应用]view与model相关梳理 前情回顾 根据之前的学习,我们形成了一个view与一个messageCenterview这块来说又内建了一套mvc的东西,我们这里来理一下首先View一层由三 ...

随机推荐

  1. [转]Laplace算子和Laplacian矩阵

    1 Laplace算子的物理意义 Laplace算子的定义为梯度的散度. 在Cartesian坐标系下也可表示为: 或者,它是Hessian矩阵的迹: 以热传导方程为例,因为热流与温度的梯度成正比,那 ...

  2. css3新增的属性

    由于CSS5标准还未完全订下来,所以各种内核的浏览器都有自己的标准,为了不使属性混淆,所以各家在各自标准前加了一个前缀, 如:-moz-       firefox火狐 -ms-         IE ...

  3. 查看linux系统的信息

    #!/bin/sh ################################################## #function:get host's information #Autho ...

  4. weight decay(权值衰减)、momentum(冲量)和normalization

    一.weight decay(权值衰减)的使用既不是为了提高你所说的收敛精确度也不是为了提高收敛速度,其最终目的是防止过拟合.在损失函数中,weight decay是放在正则项(regularizat ...

  5. python进阶之函数和类内建魔法属性

    前言 关于对象的魔法方法我们已经讲得太多,但是对于类或函数内建的魔法属性和功能我们涉及较少,下面系统了解一下类和函数的内建属性. 查看内建属性 class Person(object): pass d ...

  6. Android Bander设计与实现 - 设计

    Binder Android IPC Linux 内核 驱动 摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC ...

  7. 关于oracle数据库死锁的检查方法

    一.数据库死锁的现象程序在执行的过程中,点击确定或保存按钮,程序没有响应,也没有出现报错. 二.死锁的原理当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提交,另一条对于这一列数据做 ...

  8. android studio实现Intent通信-------牛刀小试

    概述: 本博文实现一种小程序,两个Activity单向通信,主从关系,MainActivty 页面布局一个EditText+Button,实现逻辑是单击按钮将信息发送给另外一个DisplayMessa ...

  9. Linux入门(一)root密码设置和用户切换

    从这学期开始,本人将会亲自开一个Linux 专题学习包括Linux 常用命令,常见问题的一些解决方法,以及Linux系统下C和C++一些学习经验 下面这张图片是首次安装Ubuntu后第一次设置root ...

  10. IntelliJ IDEA 里 查看一个函数注释的方法是 ctrl+q

     ctrl + q 也可以看到 官方的文档注释,java真是个强大的东西,官方的每个函数都有注释,这些注释 自动生成了官方的文档,所以看官方的注释 就是 看 官方的文档.