ZKW Splay

原创 2016年08月29日 20:58:18

来宣传我大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.


版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

ZKW Splay

来宣传我大ZKW Splay.

zkw Splay学习笔记

最近。。 最近心里颇不平静。 最近花了三天时间学了zkw Splay,发现这玩意儿真TM难写;加上各种Code Trick也还是写了好久,还有各种错误,一直在炸。 一些心得: ①维护size时不需...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

【SinGuLaRiTy-1006】 ZKW-RegTree ZKW线段树

Zkw线段树是清华大学张昆玮发明非递归线段树的写法。实践证明,这种线段树常数更小,速度更快,写起来也并不复杂。

zkw线段树

zkw线段树是zkw大神搞的自底向上线段树,以常数小,代码短著称

zkw线段树

~这是哪一题我不记得了~ zkw(重口味)线段树,是一个神奇的东西。 它可以支持区间快速查询和修改的操作。 现在我来介绍一下这个神奇的线段树吧!

ZKW线段树

zkw线段树

找对象 ssl2637 费用流

DesciptionSolution一眼题,求费用流的最小割 然后实现用了两个晚上,我果然还是太弱了。。这里需要说明的是,那些幸福度为0的情侣是不能连边的,不然会作为一条占用流量的无用边 然后这里...

zkw线段树

zkw线段树

poj3468 zkw线段树

这里使用了zkw线段树; 使标记永久化,并维护sum数组:仅考虑子树的区间和; 这样一个节点对答案的贡献就是子树和加上上方祖先的标记和; 代码中L,R数组均可省去(但由于笔者太懒。。。。。。) ...

zkw线段树

网上好多zkw线段树版本都是错的。。坑啊。 主要是连zkw的ppt上都是不完整和有错误的。统计的力量结点信息struct Node{ int sum,mx,mn; }T[maxn<<2]; in...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)