【Naive Splay Template】
写小作业的时候重新复习了一下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】的更多相关文章
- 【private HibernateTemplate template;】 的作用
[private HibernateTemplate template;] 的作用 这个是在spring中定义了一个bean,它是org.springframework.orm.hibernate3. ...
- DiscuzX2.5,X3.0,X3.1,X3.2完整目录结构【模板目录template】
/template/default/common 公共模板目录全局加载 block_forumtree.htm DIY论坛树形列表模块 block_thread.htm DIY帖子模块调用文件 ...
- [luogu3380][bzoj3196]【模板】二逼平衡树【树套树】
题目地址 [洛谷传送门] 题目大意 区间查询k的排名,查找k排名的数,单点修改,区间前驱,区间后继. 感想 真的第一次写树套树,整个人都不对了.重构代码2次,发现样例都过不了,splay直接爆炸,可能 ...
- 【机器学习Machine Learning】资料大全
昨天总结了深度学习的资料,今天把机器学习的资料也总结一下(友情提示:有些网站需要"科学上网"^_^) 推荐几本好书: 1.Pattern Recognition and Machi ...
- 【白话设计模式四】单例模式(Singleton)
转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...
- Python之路【第二十篇】其他WEB框架
WEB框架功能分析 WEB框架本质上,就是一个SOCKET Server WEB框架前面有WSGI或者是自己写的SOCKET,然后交给URL路由系统处理,然后交给某个函数或某个类,然后在模板里拿到模板 ...
- Python之路【第十七篇】:Django【进阶篇 】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- 【面试题021】包含min函数的栈
[面试题021]包含min函数的栈 MinStack.cpp: 1234567891011121314151617181920212223242526272829303132333435363738 ...
- 【单页应用】view与model相关梳理(转载)
[单页应用]view与model相关梳理 前情回顾 根据之前的学习,我们形成了一个view与一个messageCenterview这块来说又内建了一套mvc的东西,我们这里来理一下首先View一层由三 ...
随机推荐
- sklearn进行拟合
# codind:utf-8 from sklearn.linear_model import SGDRegressor,LinearRegression,Ridge from sklearn.pre ...
- 工具推荐:Backdoor-apk,安卓APK文件后门测试工具
工具推荐:Backdoor-apk,安卓APK文件后门测试工具 Backdoor-apk可以看成是一个shell脚本程序,它简化了在Android APK文件中添加后门的过程.安全研究人员在使用该工具 ...
- python 爬虫简单的demo
''' @author :Eric-chen @contact:809512722@qq.com @time :2018/1/3 17:55 @desc :通过爬取http://movie.douba ...
- 虚拟机使用主机ss代理
环境Linux mint 设置好主机ss代理,并开启[允许来自局域网的链接] 在Linux虚拟机的system setting-network手动设置代理 地址全部填入刚刚的主机地址,端口号为主机ss ...
- haproxy代理https配置方法【转】
记得在之前的一篇文章中介绍了nginx反向代理https的方法,今天这里介绍下haproxy代理https的方法: haproxy代理https有两种方式:1)haproxy服务器本身提供ssl证书, ...
- MySQL 5.7.17 Group Relication(组复制)搭建手册【转】
本博文介绍了Group Replication的两种工作模式的架构.并详细介绍了Single-Master Mode的部署过程,以及如何切换到Multi-Master Mode.当然,文末给出了Gro ...
- Fiddler大师之路系列(一)
江湖传言,Fiddler是捕获客户端与服务器之间的所有HTTP(S) 请求的利器,但是在具体使用过程中,发现使用Fiddler进行抓包时有一部分请求总是没到,多方苦寻之下发现客户端使用WinINET这 ...
- c# 通过Windows服务启动外部程序
1. 新建一个Windows服务应用程序 创建项目——>Visual C# 左侧的"+"——>Windows ——>Windows 服务(右侧模板)——>输 ...
- avalonJS-源码阅读(二)
上一篇文章讲述的avalon刷页面所用到的几个函数.这篇则是主要讲avalon对刷DOM刷出来的avalon自定义属性如何处理的. 目录[-] avalon页面处理(2) 数据结构 解析avalon标 ...
- Spark RDD 窄依赖研究
1.. 简介 spark从RDD依赖上来说分为窄依赖和宽依赖. 其中可以这样区分是哪种依赖:当父RDD的一个partition被子RDD的多个partitions引用到的时候则说明是宽依赖,否则为窄依 ...