Splay树再学习
队友最近可能在学Splay,然后让我敲下HDU1754的题,其实是很裸的一个线段树,不过用下Splay也无妨,他说他双旋超时,单旋过了,所以我就敲来看下。但是之前写的那个Splay越发的觉得不能看,所以直接学习了大神的Splay树的写法,下面的代码是CLJ上的Splay模板,有很多值得借鉴的地方,代码量比自己写短好多,下面记录下心得。
1.结点标记的add,set直接写在结点里面,更容易理解也更容易明白。
2.pushDown,pushUp也写在Node里,感觉也是漂亮许多。
3.第一次看到的 Node mem[maxn],*C=mem; 写法,这样就不用每次都 &mem[top++],直接就用C++就好,挺好的。
4.写一个作为sentinel的null,这个应该也是一个很重要的认识了吧。
5.旋转和splay两个函数都写的好妙。
6.用get传出【l,r)的区间的结点,之前没有当成一个函数写不太漂亮。
附上大神的模板权当学习。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define INF 0x3fffffff
#define maxn 200100
using namespace std; struct Node
{
Node *ch[2],*p;
int size,val,mx;
int set;
bool rev;
Node(){
size=0;
val=mx=-INF;
set=-1;
}
bool d(){
return this==p->ch[1];
}
void setc(Node *c,int d){
ch[d]=c;
c->p=this;
}
void setIt(int se){
set=mx=val=se;
}
void revIt(){
rev^=1;
}
void pushDown(); // pushDown();
void pushUp(){
size=ch[0]->size+ch[1]->size+1;
mx=max(val,max(ch[0]->mx,ch[1]->mx));
}
}Tnull,*null=&Tnull; Node mem[maxn+50],*C=mem;
int a[maxn+50]; void Node::pushDown(){
if(set!=-1){
for(int i=0;i<2;++i){
if(ch[i]!=null) ch[i]->setIt(set);
}
set=-1;
}
if(rev){
swap(ch[0],ch[1]);
for(int i=0;i<2;++i){
if(ch[i]!=null) ch[i]->revIt();
}
rev=0;
}
} Node *make(int v){
C->ch[0]=C->ch[1]=null;
C->size=1;
C->val=C->mx=v;
C->set=-1;C->rev=0;
return C++;
} Node *build(int l,int r)
{
if(l>=r) return null;
int m=(l+r)>>1;
Node *t=make(a[m]); // 根据数组建值,建空值则t=make(0);
t->setc(build(l,m),0);
t->setc(build(m+1,r),1);
t->pushUp();
return t;
} Node *root; void rot(Node *t){
Node *p=t->p;
p->pushDown();
t->pushDown();
int d=t->d();
p->p->setc(t,p->d());
p->setc(t->ch[!d],d);
t->setc(p,!d);
p->pushUp();
if(p==root)
root=t;
} void splay(Node *t,Node *f=null){
while(t->p!=f){
if(t->p->p==f){
rot(t);
}
else{
t->d()==t->p->d()? (rot(t->p),rot(t)):(rot(t),rot(t));
}
}
t->pushUp();
} Node *select(int k){
for(Node *t=root;;){
t->pushDown();
int c=t->ch[0]->size;
if(k==c) {
return t;
}
if(k>c) {
k-=c+1,t=t->ch[1];
}
else{
t=t->ch[0];
}
}
} Node*&get(int l,int r){ //[l,r)
Node *L=select(l-1);
Node *R=select(r);
splay(L);
splay(R,L);
return R->ch[0];
} int n,m; int main()
{
while(cin>>n>>m)
{
C=mem;
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
root=build(0,n+2);
root->p=null;
char str[3];int l,r;
for(int i=0;i<m;++i){
scanf("%s%d%d",str,&l,&r);
if(strcmp(str,"Q")==0){
Node*&t=get(l,r+1);
printf("%d\n",t->mx);
}
else{
Node*&t=get(l,l+1);
t->setIt(r);
}
}
}
return 0;
}
Splay树再学习的更多相关文章
- 暑假学习日记:Splay树
从昨天开始我就想学这个伸展树了,今天花了一个上午2个多小时加下午2个多小时,学习了一下伸展树(Splay树),学习的时候主要是看别人博客啦~发现下面这个博客挺不错的http://zakir.is-pr ...
- 文艺平衡Splay树学习笔记(2)
本blog会讲一些简单的Splay的应用,包括但不局限于 1. Splay 维护数组下标,支持区间reserve操作,解决区间问题 2. Splay 的启发式合并(按元素多少合并) 3. 线段树+Sp ...
- Splay树学习
首先给出一论文讲的很好: http://www.docin.com/p-63165342.html http://www.docin.com/p-62465596.html 然后给出模板胡浩大神的模板 ...
- 1439. Battle with You-Know-Who(splay树)
1439 路漫漫其修远兮~ 手抄一枚splay树 长长的模版.. 关于spaly树的讲解 网上很多随手贴一篇 貌似这题可以用什么bst啦 堆啦 平衡树啦 等等 这些本质都是有共同点的 查找.删除特 ...
- [Splay伸展树]splay树入门级教程
首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...
- 【集训第二天·翻水的老师】--ac自动机+splay树
今天是第二天集训.(其实已经是第三天了,只是昨天并没有机会来写总结,现在补上) 上午大家心情都很愉快,因为老师讲了splay树和ac自动机. 但到了下午,我们的教练竟然跑出去耍了(excuse me? ...
- bzoj 3224: Tyvj 1728 普通平衡树 && loj 104 普通平衡树 (splay树)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 思路: splay树模板题: 推荐博客:https://blog.csdn.ne ...
- Splay树分析
简述 Splay树是一种二叉查找平衡树,其又名伸展树,缘由是对其进行任意操作,树的内部结构都会发生类似伸张的动作,换言之,其读和写操作都会修改树的结构.Splay树拥有和其它二叉查找平衡树一致的读写时 ...
- poj 3468 Splay 树
大二上的时候.写过一个AVL的操作演示,今天一看Splay.发现和AVL事实上一样,加上线段树的基础,懒惰标记什么都知道.学起来轻松很多哦 我參考的模板来自这里 http://blog.csdn.n ...
随机推荐
- format——MATLAB
format:设置输出格式 对浮点性变量,缺省为format short. format并不影响matlab如何计算和存储变量的值.对浮点型变量的计算,即单精度或双精度,按合适的浮点精度进行,而不论变 ...
- C++中extern “C”含义深层探索
C++中extern “C”含义深层探索 extern “C” 是一个双向都需要用到的语法表示,就是说在cpp引用c头文件,或者c引用cpp文件时都需要用到.但extern “C” 永远只能在cpp引 ...
- NDK 通过java调用so文件
首先我们来看so文件的来源 1. 自己写.c文件,然后生成so库 2. 引用别人的静态库,或者动态库来生成新的jni调用库. 我们先来看最简单的编写一个jni调用的so库,包含一个获取字符串的方法,通 ...
- Mysql数据库常用的命令 数据备份 恢复 远程
远程数据库 格式: mysql -h主机地址 -u用户名 -p用户密码数据库 mysql -h 42.51.150.68 -u yang -p discuz mysql设置密码 mysql>us ...
- 【Qt】QDialog之屏蔽Esc键【转】
简述 Qt中Esc键会在一些控件中默认的进行一些事件的触发,比如:QDialog,按下Esc键窗口消失.大多数情况下,我们不需要这么做,那么就需要对默认事件进行屏蔽. 简述 源码分析 事件过滤器 事件 ...
- WinDbg 调试.net程序
WinDbg支持以下三种类型的命令: · 常规命令,用来调试进程 · 点命令,用来控制调试器 · 扩展命令,可以添加叫WinDbg的自定义命令,一般由扩展dl ...
- struts2 知识梳理
写此文章时,最新struts2版本:2.3.6 一:struts.xml配置详解: 1.<include> 表示引入其他配置文件 2.<constant> 定义常量 3.< ...
- 婚庆手机APP
这是一个信息化的时代,即将步入婚姻殿堂的新人们,你们是否希望有这样一款手机软件能伴随你从结婚到婚后一路的历程呢?比如说请帖通过手机客户端来将结婚的时间地点流程共享给您的亲朋好友,将您的婚纱照.随拍.写 ...
- Game Tutorials
SDL: http://www.sdltutorials.com/tutorials http://lazyfoo.net/ http://panda3d.noie.name/ http ...
- Selenium-RC Python 2.7 环境配置
1.下载并安装Python http://www.python.org/getit/,我使用的是2.7.3的python版本 2.下载并安装setuptools[这个工具是python的基础包工具] ...