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 ...
随机推荐
- Window Phone 8开发问题反思
项目开发有段时间了,进入了阶段测试.然而在测试过程中bug连连不断,在抱怨产品需求的坑爹.不合理之外,我也一直在反思为什么会出现这么多Bug. 首先,由于项目开发的两个人都是新手,在刚刚认识MVVM架 ...
- c++11: less的用法
less主要是重载了operator()方法,用来比较lhs 和 rhs std::less::operator() bool operator()(const T &lhs, const T ...
- silverlight Frame嵌套页面刷新问题
1.此方法将会刷新到主页面 private void btn_Click(object sender, RoutedEventArgs e) { HtmlPage.Window.Eval(" ...
- [大牛翻译系列]Hadoop(7)MapReduce:抽样(Sampling)
4.3 抽样(Sampling) 用基于MapReduce的程序来处理TB级的数据集,要花费的时间可能是数以小时计.仅仅是优化代码是很难达到良好的效果. 在开发和调试代码的时候,没有必要处理整个数据集 ...
- php获取系统信息的方法
php获取系统信息的方法. 用 getenv函数进行处理: <?php $root = getenv('DOCUMENT_ROOT'); ////服务器文档根目录 $port = getenv( ...
- android 在标题栏加上按钮
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowF ...
- Global::validateEmail
/***************************************************************** (C) Copyright DENTSPLY Internatio ...
- Noppoo choc mini 84 @XUbuntu13.10 compatibility setting
Months ago, I bought the keyboard Noppoo Choc Mini 84keys for using under XUbuntu12.10, and I have f ...
- 每日一“酷”之textwrap
介绍:需要美观打印时,可以使用textwrap模块来格式化要输出的文本,这个模块允许通过编程提高类似段落自动换行或填充特性等功能. 1 创建实例数据 sample_text = ''' I’m ver ...
- 【转】如何在 Windows 中执行干净启动
完成故障排除后,请执行以下步骤将计算机重置为正常启动. Windows 8.1 和 Windows 8 从屏幕右边缘滑入,然后点按“搜索”.您也可以将鼠标指向屏幕的右下角,然后单击“搜索”. 在搜索框 ...