zkw Splay学习笔记
来源:互联网 发布:用c语言求以内素数 编辑:程序博客网 时间:2024/06/05 11:07
最近。。
最近心里颇不平静。
最近花了三天时间学了zkw Splay,发现这玩意儿真TM难写;加上各种Code Trick也还是写了好久,还有各种错误,一直在炸。
一些心得:
①维护size时不需要考虑太多东西,只需要改变孩子指针后直接用孩子的size维护即可,注意要在两个地方维护:
旋转的时候维护;
翻转子树链表的时候维护。
②zkw Splay中左临时树是一些没有右孩子子树的节点,然后。。为了方便(真的方便么。。),我们可以一开始用每棵子树的右儿子存储它的父节点,然后再把根表反转。
反转真是一件蛋疼的事,注意到新根也还是有左右子树的,所以其实就相当于从一个根表的表头加入另一个根表的表头。(!!这玩意儿我想了好久才想明白,真是坑爹。)
③Select中向下探测两层真的是一件很蛋疼的事,我是通过人工让两层不一样以解决在下一层取到所需节点的问题的。
④最重要的:一定要时刻注意变量的意义!它改变了没有?它现在是什么!尤其是在坑爹的表头插入和维护的时候。。经常弄错导致炸飞。
⑤zkw。。真是太牛了!我感觉我现在的代码能力还不太能驾驭得了zkw Splay。。以后如果没有被卡就还是都老老实实写普通Splay吧。。
代码(模板题-普通平衡树):
#include<iostream>using namespace std;#include<cstdio>#include<cstring>#include<algorithm>struct SS{SS * c[2];int key,num,size;}* null=new SS((SS){null,null,0,0,0}),* root=new SS((SS){null,null,0x7fffffff,1,1}),* newroot=new SS((SS){null,null,0,0,0});inline void mtn(){SS * now,* next;for(int D=0;D<2;++D)for(now=newroot->c[D];now!=null;now=next){next=now->c[D];now->c[D]=root->c[!D];root->c[!D]=now;now->size=now->c[0]->size+now->c[1]->size+now->num;}root->size=root->c[0]->size+root->c[1]->size+root->num;newroot->c[0]=null;newroot->c[1]=null;}inline void search(int A){bool D;SS * tmp;while(root->key!=A){D=root->key<A;if(root==null){root=new SS((SS){null,null,A,0,0});break;}if(root->c[D]!=null&&root->c[D]->key!=A&&D==(root->c[D]->key<A)){tmp=root->c[D];root->c[D]=tmp->c[!D];tmp->c[!D]=root;root->size=root->c[0]->size+root->c[1]->size+root->num;root=tmp;}if(root==null){root=new SS((SS){null,null,A,0,0});break;}tmp=root->c[D];root->c[D]=newroot->c[D];newroot->c[D]=root;root=tmp;}mtn();}inline void select(int A){bool D,d;SS * tmp;while(1){D=root->size-root->c[1]->size<A;if(!D&&root->c[0]->size<A)break;if(D)A-=root->size-root->c[1]->size;if(root->c[D]->c[0]->size<A&&root->c[D]->size-root->c[D]->c[1]->size>=A)d=!D;else d=root->c[D]->size-root->c[D]->c[1]->size<A;if(D==d){if(d)A-=root->c[1]->size-root->c[1]->c[1]->size;tmp=root->c[D];root->c[D]=tmp->c[!D];tmp->c[!D]=root;root->size=root->c[0]->size+root->c[1]->size+root->num;root=tmp;}tmp=root->c[D];root->c[D]=newroot->c[D];newroot->c[D]=root;root=tmp;}mtn();}char * ptr=(char *)malloc(2000000);inline void in(int &x){bool flag=0;while(*ptr<'0'||*ptr>'9')if(*ptr++=='-')flag=1;x=0;while(*ptr>47&&*ptr<58)x=x*10+*ptr++-'0';if(flag)x=-x;}int main(){freopen("phs.in","r",stdin);freopen("phs.out","w",stdout);fread(ptr,1,2000000,stdin);int N,ans,opt,x;in(N);SS * tmp;while(N--){in(opt),in(x);switch(opt){case 1:search(x);++root->num;++root->size;break;case 2:search(x);if(!--root->num){tmp=root;root=root->c[1];select(1);root->c[0]=tmp->c[0];root->size+=root->c[0]->size;delete tmp;}else --root->size;break;case 3:search(x);printf("%d\n",root->c[0]->size+1);break;case 4:select(x);printf("%d\n",root->key);break;case 5:ans=-0x7fffffff;tmp=root;while(tmp!=null)if(tmp->key>=x)tmp=tmp->c[0];else{ans=max(tmp->key,ans);tmp=tmp->c[1];}printf("%d\n",ans);break;case 6:ans=0x7fffffff;tmp=root;while(tmp!=null)if(tmp->key<=x)tmp=tmp->c[1];else{ans=min(tmp->key,ans);tmp=tmp->c[0];}printf("%d\n",ans);}}}
0 0
- zkw Splay学习笔记
- ZKW Splay
- zkw学习笔记
- Splay学习笔记
- Splay学习笔记
- Splay Trees 学习笔记
- splay tree 学习笔记
- 【数据结构】Splay学习笔记
- splay 学习笔记
- Splay树 学习笔记一
- splay学习笔记及模板
- 学习笔记--(平衡树)splay
- 伸展树Splay学习笔记
- 【zkw线段树套自顶向下splay】cf44g
- 学习一个ZKW线段树
- [学习笔记] bzoj3224 普通平衡树:splay模板
- HDU 1754 I Hate It 线段树 && Splay && zkw线段树
- Splay学习--初篇
- 工具简介(一)--Git
- 两种方法模仿支付宝进入到后台界面模糊
- 静态字符串的连接操作
- Java中的String为什么是不可变的? -- String源码分析
- HTML之Canvas基础
- zkw Splay学习笔记
- qgis 源码学习之core的gps模块
- redis 源码学习(核心数据结构剖析)
- android Studio安装详解
- Maven(一) Maven的安装
- Java多线程一捋
- 5行代码怎么实现Hadoop的WordCount?
- 苹果语音
- java 构造函数(本例意在说明如果一个类里定义了构造函数,则系统不会再给定义默认的无参构造函数)