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 ...
随机推荐
- Windows下OpenCV的环境配置
首先去官网下载所需版本的OpenCV(我这里下载的是OpenCV2.4.9),然后安装(也就是解压缩)到某个地方(个人推荐解压到硬盘的根目录).解压完成后,可以得到如下的目录结构(版本不同,可能会有一 ...
- unity 多线程
对于客户端来说,好的用户体验,需要保持一个快速响应的用户界面.于是便要求:网络请求.io操作等 开销比较大的操作必须在后台线程进行,从而避免主线程的ui卡顿.(注:协程也是主线程的一部分,进行大量的i ...
- Linux C 程序 线程(18)
线程控制 1.线程与进程的关系 线程:计算机中独立运行的最小单位. 在用户角度:多个线程是同时执行的. 操作系统角度:各个线程交替执行 以上只针对单核CPU的情况 在多核CPU主机上,多个线程可以同时 ...
- 读取XML
public sealed class ConfigManger { public XDocument XmlDocs { set; get; } string path = @"{0}\C ...
- [大牛翻译系列]Hadoop(22)附录D.2 复制连接框架
附录D.2 复制连接框架 复制连接是map端连接,得名于它的具体实现:连接中最小的数据集将会被复制到所有的map主机节点.复制连接的实现非常直接明了.更具体的内容可以参考Chunk Lam的<H ...
- Ubuntu 12.04 修改默认启动为字符界面
sudo vim /etc/default/grub 修改GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" 为:GRUB_CMDLINE_LINU ...
- 正则PerlRegEx实现的批量替换指定文件中的标签
示例: 一个朋友需要而编写的标签升级更新. 速度超快,1w个文件大概4,5秒,本想加个多线程显示进度,后来想想算了 主要代码: reg.RegEx := '<' + Edit_regular1. ...
- Nginx+Tomcat动静分离
需求:nginx处理用户请求的静态页面,tomcat处理用户请求jsp页面,来实现动态分离,nginx处理静态页面效率远高于tomcat,这样一来就能更好的提高并发,处理性能. 准备软件: 下载jdk ...
- mysql-5.5.46源码编译安装
1.安装准备 cat /etc/redhat-release uname -r yum install ncurses-devel cmake automake autoconf make gcc g ...
- 1094. The Largest Generation (25)
A family hierarchy is usually presented by a pedigree tree where all the nodes on the same level bel ...