【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一层由三 ...
随机推荐
- pandas 对时间与日期处理
1.先把字符串时间转为时间类型: def func(x): y =pd.Timestamp(x) return y data.index = data.发博时间.apply(lambda x : fu ...
- [转]程序进行性能分析工具gprof使用入门
性能分析工具 软件的性能是软件质量的重要考察点,不论是在线服务程序还是离线程序,甚至是终端应用,性能都是用户体验的关键.这里说的性能重大的范畴来讲包括了性能和稳定性两个方面,我们在做软件测试的时候也是 ...
- [LeetCode] #112 #113 #437 Path Sum Series
首先要说明二叉树的问题就是用递归来做,基本没有其他方法,因为这数据结构基本只能用递归遍历,不要把事情想复杂了. #112 Path Sum 原题链接:https://leetcode.com/prob ...
- Oracle环境变量与中文显示的问题
在CentOS(linux)下安装Oracle,对环境变量的设置有一些讲究. 一般我们可以把环境变量设置在/etc/profile文件中: # Oracle SettingsTMP=/tmp; exp ...
- iptables NAT规则【转】
nat表需要的三个链: 1.PREROUTING:可以在这里定义进行目的NAT的规则,因为路由器进行路由时只检查数据包的目的ip地址,所以为了使数据包得以正确路由,我们必须在路由之前就进行目的NAT; ...
- Ubuntu 12.04下LVM2安装和操作实验
实验环境: VirtualBox v4.3.20 Lubuntu 12.04LTS 前期准备: 1.添加虚拟盘:菜单"控制"->"设置"->&quo ...
- centos7.2系统没有eth0网卡
最近一直在学centos7.5系统,偶然看到虚拟机里有7.2系统所以想练习一下(其实7.2和7.5差不多),但是打开虚拟机之后,发现没有eth0网卡 那没有eth0网卡就无法远程连接ssh,既然遇到了 ...
- 读书笔记--C陷阱与缺陷(三)
第三章 1. 指针与数组 书中强调C中数组注意的两点: 1) C语言只有一维数组,但是数组元素可以是任何类型对象,是另外一个数组时就产生了二维数组.数组大小是常数(但GCC实现了变长数组..) ...
- kickstart配置LINUX无人值守选项--rootpw
linux kickstart rootpw密码可以使用明文,也可以使用加密过的值(密码为:IPPBXADMINROOT) 注意:在这里要使用加密过的值,否则安全性就太低了 rootpw --iscr ...
- sqlserver游标概念与实例全面解说
引言 我们先不讲游标的什么概念,步骤及语法,先来看一个例子: ?????? 表一 OriginSalary????????????????????????????????????????????? ...