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 ...
随机推荐
- codevs 3186 队列练习2
3186 队列练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description (此题与队列练习1相比改了2处:1加 ...
- 简单版解决IE兼容性问题
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 在访问页面时, 如 ...
- ADO.NET笔记——使用DataAdapter执行增删改操作
相关知识: DataSet中的数据一旦从数据库下载下来,便不再与数据库保持联系.如果修改了DataSet中的数据,需要重新建立连接,并且通过SQL命令将修改更新到数据库去 编写SQL命令往往比较繁琐和 ...
- Turn.js 实现翻书效果的学习与总结
最近CTO给我分配了一个移动端H5开发的任务,主要功能是需要实现翻书效果,我听过主要需求后,当时是呀!!!接下来自己尝试使用fullPage.js和Swiper来实现翻书效果,结果效果都不是非常的理想 ...
- HTML5 Shiv – 让该死的IE系列支持HTML5吧
HTML5能为我们做的事儿很多,最为可口的就是语义化标签的应用,如果你已经在Chrome或者其他支持HTML5的浏览器上用过它的牛x,那这篇文章对你一定有用,因为现在你也可以在IE上用到HTML5. ...
- mina socket底层主流程源码实现
一,mina的架构 mina 架构可以大致分为三部分,ioService ,ioFilterChain , IoHandler ioService:用于接受服务或者连接服务,例如socket 接收 ...
- Ubuntu 在未知root密码的情况下修改root密码
一, 开机按 F12 (或长按Shift), 进入GRUB界面. 二, 在 recovery mode 按e Ubuntu, Linux 3.5.0-17-generic (恢复模式) (或recov ...
- PHP学习之数组的定义和填充
数组就是把一组数据按顺序放在一起.PHP的数组和其它的语言数组有一点点不同:第一,保存的数据是可以是任何类型的:第二,数组的索引可以是数字,也可以是字符串. PHP的数组,说白了,就是关联数据每一条数 ...
- php intval()函数
格式:int intval(mixed $var [, int $base]); 1.intval()的返回值是整型,1或者0.可作用于数组或者对象(对象报错信息:Notice: Object of ...
- php实现查询百度google收录情况(示例代码)
对了貌似查google pr的东西只是file一个地址而已,如此说了就没有什么难度了.完整代码如下 写了一个小东西记录baidu和google对于站点的收录情况,现在可以查询了,其实也没什么难度,就是 ...