class SplayNode {
public:
SplayNode *child[];
char value;
int size;
bool flip;
SplayNode(char c) : value(c), size(), flip(false) {
child[] = child[] = NULL;
}
int getPosition()const {
return child[] ? child[]->size + : ;
}
void maintain() {
size = ;
if (child[]) {
size += child[]->size;
}
if (child[]) {
size += child[]->size;
}
}
void pushDown() {
if (flip) {
swap(child[], child[]);
for (int i = ; i < ; i++) {
if (child[i]) {
child[i]->flip ^= ;
}
}
flip = false;
}
}
};
class SplayTree {
public:
SplayNode *root;
SplayTree(char *a, int n);
void build(SplayNode *&node, char *begin, char *end);
void rotate(SplayNode *&node, int direction);
void splay(SplayNode *&node, int position);
void reverse(int begin, int end);
void traverse(SplayNode *u);
void traverse();
};
SplayTree::SplayTree(char *a, int n) {
build(root, a, a + n - );
}
void SplayTree::build(SplayNode *&node, char *begin, char *end) {
if (begin > end) {
return;
}
char *middle = begin + (end - begin >> );
node = new SplayNode(*middle);
build(node->child[], begin, middle - );
build(node->child[], middle + , end);
node->maintain();
} void SplayTree::rotate(SplayNode *&node, int direction) {
SplayNode *child = node->child[direction ^ ];
node->child[direction ^ ] = child->child[direction];
child->child[direction] = node;
node->maintain();
child->maintain();
node = child;
}
void SplayTree::splay(SplayNode *&node, int position) {
node->pushDown();
if (node->getPosition() != position) {
int d = node->getPosition() < position;
SplayNode *node2 = node->child[d];
position -= d ? node->getPosition() : ;
node2->pushDown();
if (node2->getPosition() != position) {
int d2 = node2->getPosition() < position;
position -= d2 ? node2->getPosition() : ;
splay(node2->child[d2], position);
if (d == d2) {
rotate(node, d ^ );
} else {
rotate(node->child[d], d);
}
}
rotate(node, d ^ );
}
}
void SplayTree::reverse(int begin, int end) {
splay(root, begin);
splay(root->child[], end - begin + );
root->child[]->child[]->flip ^= ;
}
void SplayTree::traverse(SplayNode *u) {
if (!u) {
return;
}
u->pushDown();
traverse(u->child[]);
if (u->value) {
printf("%c", u->value);
}
traverse(u->child[]);
}
void SplayTree::traverse() {
traverse(root);
}

Splay(root,p)表示 把以root为根的子树中前序遍历的第p个元素旋转到root子树的树根位置

这个代码风格跟我不一样,晚上回去改一改。太菜了,改不了。

Splay树的旋转过程按照二叉搜索树的性质操作,保证前序遍历是不变的。但是就节点值来说,未必满足二叉搜索树的性质(大概此时可以把节点值理解为<key,value>的键值对吧,只不过此时value值具体是多少根本没什么影响,就忽略掉了)......

如何应用就有些困惑了,跟序列操作有关系的问题大概能往这个方面考虑一下,感觉就是以另一种思路实现了线段树的功能......但是能做一些线段树做不了的操作,比如区间反转,而且比线段树慢,别的一时就想不到了,还是刷题太少的缘故。

Splay树的更多相关文章

  1. Splay树-Codevs 1296 营业额统计

    Codevs 1296 营业额统计 题目描述 Description Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司 ...

  2. ZOJ3765 Lights Splay树

    非常裸的一棵Splay树,需要询问的是区间gcd,但是区间上每个数分成了两种状态,做的时候分别存在val[2]的数组里就好.区间gcd的时候基本上不支持区间的操作了吧..不然你一个区间里加一个数gcd ...

  3. Splay树再学习

    队友最近可能在学Splay,然后让我敲下HDU1754的题,其实是很裸的一个线段树,不过用下Splay也无妨,他说他双旋超时,单旋过了,所以我就敲来看下.但是之前写的那个Splay越发的觉得不能看,所 ...

  4. 暑假学习日记:Splay树

    从昨天开始我就想学这个伸展树了,今天花了一个上午2个多小时加下午2个多小时,学习了一下伸展树(Splay树),学习的时候主要是看别人博客啦~发现下面这个博客挺不错的http://zakir.is-pr ...

  5. 1439. Battle with You-Know-Who(splay树)

    1439 路漫漫其修远兮~ 手抄一枚splay树 长长的模版.. 关于spaly树的讲解   网上很多随手贴一篇 貌似这题可以用什么bst啦 堆啦 平衡树啦 等等 这些本质都是有共同点的 查找.删除特 ...

  6. 伸展树(Splay树)的简要操作

    伸展树(splay树),是二叉排序树的一种.[两个月之前写过,今天突然想写个博客...] 伸展树和一般的二叉排序树不同的是,在每次执行完插入.查询.删除等操作后,都会自动平衡这棵树.(说是自动,也就是 ...

  7. [Splay伸展树]splay树入门级教程

    首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...

  8. hdu 3436 splay树+离散化*

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  9. hdu 1890 splay树

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  10. hdu3487 splay树

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

随机推荐

  1. Eclipse 插件ibeetl

    启动Eclipse 打开菜单栏按一下菜单路径依次打开 Help -> Install New Softwave… ->点击Add按钮弹出一个对话框 弹出的对话框中Name随意填写,如填写“ ...

  2. 在Android 上运行 openCV ,并做灰度变化的一个例子

    OpenCVImageProcessing1. 导入Opencv的 androrid SDK灰度算法 OpenCVImageProcessing 导入opencv Jar包,配置OpenCVLibra ...

  3. null值处理

    一,在实体类的上面加注解 import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NO ...

  4. es 存入失败错误

    {, 'error': {'type': 'illegal_argument_exception', 'reason': 'Rejecting mapping update to [bd_date] ...

  5. linux中php项目无法发送邮件:PEAR mail package is not installed

    发送邮件报错误:PEAR mail package is not installed的原因是linux中缺少PEAR mail组件, PEAR mail组件也就是PHP Pear Mail / SMT ...

  6. 3分钟实现小程序唤起微信支付 Laravel教程

    微信支付的接入,如果不使用成熟的开发包,将是巨大的工作量. 依赖 EasyWechat 先在 laravel 项目中依赖 easywechat 这个包 composer require "o ...

  7. 【Codeforces Round #519 by Botan Investments D】Mysterious Crime

    [链接] 我是链接,点我呀:) [题意] 相当于问你这m个数组的任意长度公共子串的个数 [题解] 枚举第1个数组以i为起点的子串. 假设i..j是以i开头的子串能匹配的最长的长度. (这个j可以给2. ...

  8. 数据库工具——Navicat Premium使用技巧

    Navicat Premium 常用功能讲解 1.快捷键 1.1. F8 快速回到当前对象列表  1.2. Ctrl + q 打开查询界面  1.3. Ctrl + d 快速修改当前的表结构  1.4 ...

  9. 【ACM】NYOJ_506_洗澡_20130725

    洗澡时间限制:1000 ms  |  内存限制:65535 KB 难度:1描述 Mostrp是个爱干净的好少年. 有一次去澡堂洗澡时发现 澡堂的澡柜编号中没有出现过数字‘4’. Mostrp 感到很好 ...

  10. ZOJ 1450

    最小圆覆盖 #include <iostream> #include <algorithm> #include <cstdio> #include <cmat ...