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 ...
随机推荐
- ZigBee profile
每个ZigBee设备都与一个特定模板相关联,可能是公共模板或私有模板.这些模板定义了设备的应用环境.设备类型以及用于设备间通信的簇.采用公共模板,可以确保不同供应商的设备在相同应用领域的互操作 ...
- windows phone 自定义铃声
屌丝的电话是一个月都响不了几次的,无聊还是下了一个XX铃声,自娱自乐一下,google了一下实现原理,,,,,,真相啊!!!就是用了一个Task(SaveRingtoneTask),以前看的资料都没有 ...
- adb连接不上手机
昨天电脑重装了系统,今天打开之前的eclips工作环境,点击run as -> android application,一直报各种诡异的错误,总之就是连接不上手机. 其中包括 Adb conne ...
- Windows7系统禁用USB和启用USB方法
被迫装了XX软件之后,无线网络和USB都被禁用了,XX软件还不能被卸载.只能用PE进去时候把XX软件安装目录进行删除,但是删除之后还是不能识别U盘,从网上找到办法一看是注册表的项被修改了. 注册表项为 ...
- sql server 查询多个不关联表且对结果编号
1.除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图.内联函数.派生表.子查询和公用表表达式中无效. 解决方法:top 100 percent * 2.如何对查询结果编 ...
- react-native-vector-icons 安装
react-native-vector-icons 是可以直接使用图片名就能加载图片的第三方,类似于web的iconfont矢量图,使用很方便, 你不需要在工程文件夹里塞各种图片, 节省很多空间,下面 ...
- 选项切换条--第三方开源--SHSegmentControl
SHSegmentControl在github上的项目主页地址:https://github.com/7heaven/SHSegmentControl SHSegmentControl使用简单,在xm ...
- wxPython + Boa 练习程序
最近需要做点支持linux的跨平台gui,网上查到了wxPython及Boa,感觉不错,照着Boa文档做做练习. 代码: App: #!/usr/bin/env python #Boa:App:Boa ...
- getchar(),gets(),scanf()的差异比较
scanf( )函数和gets( )函数都可用于输入字符串,但在功能上有区别.若想从键盘上输入字符串"hi hello",则应该使用gets()函数. gets可以接收空格:而sc ...
- Error NO.2013 Lost connection to Mysql server during query
系统:[root@hank-yoon ~]# cat /etc/redhat-release CentOS release 6.3 (Final) DB版本:mysql> select @@ve ...