ZKW Splay

来源:互联网 发布:mac office mathtype 编辑:程序博客网 时间:2024/06/18 03:48

来宣传我大ZKW Splay.

没错这就是我说的Splay的奇怪姿势,貌似很少人知道?

据某论文所说常数是一般Splay的一半(没记错的话233).


大多数Splay自底向上,而我大ZKW Splay自顶向下.

基本操作是“zig”和“zigzig”,分别为“单旋”和“双旋”.

核心操作为search,select,所有的操作在root点展开.

search是在树上查找满足大小条件的一个点.

search时,从根节点向下走,之前经过的点,连同它的另一子树,都挂到一个链表上(像晾毛巾一样).

当根节点为要找的点时,停下来,这时候暴力把晾起来的“毛巾”挂回去.


select是在树上查找第k大的点.

原理和search相似.


用神奇的缩行可以把行数压在八、九十行(附带插入删除第k大).

由于,每次search,select操作会使树的形态发生变化,所以不能可持久化.

虽然自顶向下但也可以支持LCT.


最后 :

onst int oo=(1LL << 31)-1;struct node {int key,size;node *c[2];node(): key(0),size(0){c[0]=c[1]=this;}node(int kk,node* c0,node* c1): key(kk){c[0]=c0;c[1]=c1;}node* rz() {return size=c[0]->size+c[1]->size+1,this;}}Tnull,*null=&Tnull;node *last[2];struct splay {node *root;splay() {root=(new node(*null))->rz();root->key=oo;}void zig(bool w) {last[w]=root;node *t=root->c[w];root->c[w]=null->c[w];null->c[w]=root;root=t;}void zigzig(bool w) {last[w]=root->c[w];node *t=root->c[w]->c[w];root->c[w]->c[w]=null->c[w];null->c[w]=root->c[w];root->c[w]=null->c[w]->c[!w];null->c[w]->c[!w]=root->rz();root=t;}void finish(bool w) {node *t=null->c[w],*p=root->c[!w];while (t!=null) {t=null->c[w]->c[w];null->c[w]->c[w]=p;p=null->c[w]->rz();null->c[w]=t;}root->c[!w]=p;}void select(int k) {int t;for (;;) {bool w=k>(t=root->c[0]->size);if (k==t|| root->c[w]==null) break;if (w) k-=t+1;bool ww=k>(t=root->c[w]->c[0]->size);if (k==t || root->c[w]->c[ww]==null) {zig(w);break;}if (ww) k-=t+1;w!=ww?zig(w),zig(ww):zigzig(w);}finish(0),finish(1);root->rz();}void search(int x) {for (;;) {bool w=x>root->key;if (root->c[w]==null) break;bool ww=x>root->c[w]->key;if (root->c[w]->c[ww]==null) {zig(w);break;}w!=ww?zig(w),zig(ww):zigzig(w);}finish(0); finish(1);root->rz();if (x>root->key) select(root->c[0]->size+1);}void ins(int x) {search(x);node *oldroot=root;root=new node(x,oldroot->c[0],oldroot);oldroot->c[0]=null;oldroot->rz();root->rz();}void del(int x) {search(x);node *oldroot=root;root=root->c[1];select(0);root->c[0]=oldroot->c[0];root->rz();delete oldroot;}int sel(int k) {return select(k-1),root->key;}int ran(int x) {return search(x),root->c[0]->size+1;}};


最最后,orz ZKW.


0 0