splay模板(真難寫)

更新當前節點的狀況

void update(int rt){
	t[rt].sz = t[rt].cnt + t[t[rt].ch[0]].sz + t[t[rt].ch[1]].sz;
}

判斷自己是父親的左右兒子

void get(int rt){
	return (t[rt].f == t[t[rt].f].ch[1]);
}

喜聞樂見的旋轉操作(把他分爲三個部分就好記憶一點分別是爺爺,爸爸,兒子(三代同堂))

int rote(int rt){
	int d = get(rt);
	int ff = t[rt].f;
	if(ff == 0)return 0;
	int gg = t[ff].f;
	int cc = t[rt].ch[d ^ 1];
	if(gg)t[gg].ch[get(ff)] = rt;
	t[rt].f = gg;
	t[rt].ch[d ^ 1] = ff;
	if(ff)t[ff].f = rt;
	t[ff].ch[d] = cc;
	if(cc)t[cc].f = ff;
	update(ff);
	update(rt);
}

splay到根

int splay(int rt){
	int d;
	for(int f = t[rt].f ; (f = t[rt].f) ; rote(rt)){
		if(get(f) == get(rt))rote(f);
		else rote(rt);
	}
	op = rt;
}

插入。。。

int add(int rt , int dx){
		if(!rt){
			rt = ++tot;
			op = rt;
			t[rt].sz = t[rt].cnt = 1;
			t[rt].val = dx;
			t[rt].f = 0;
			return 0;
		}
		int d;
		while(1){
			if(t[rt].val == dx){
				t[rt].cnt++;
				splay(rt);
				return 0;
			}
			d = (t[rt].val < dx);
			if(!t[rt].ch[d]){
				t[rt].ch[d] = ++tot;
				t[tot].cnt = t[tot].sz = 1;
				t[tot].val = dx;
				t[tot].f = rt;
				splay(tot);
				return 0;
			}
			rt = t[rt].ch[d];
		}	
	}

刪除

int del(int dx){
		rank(op , dx);
		if(t[op].cnt > 1){
			t[op].cnt--;
			return 0;
		}
		if(!t[op].ch[0] && !t[op].ch[1]){
			op = 0;
			return 0;
		}
		if(!t[op].ch[0]){
			t[t[op].ch[1]].f = 0;
			op = t[op].ch[1];
			return 0;
		}
		if(!t[op].ch[1]){
			t[t[op].ch[0]].f = 0;
			op = t[op].ch[0];
			return 0;
		}
		splay(nxt(op));
		t[op].ch[1] = t[t[op].ch[1]].ch[1];
		t[t[op].ch[1]].f = op;
		up(op);
	}

注意別寫錯就好了。。。。。記得後面是吧前驅splay上來,然後刪除就好了。。。
其他的沒什麼好強調的了

#include<bits/stdc++.h>
#define MAXN 200005
using namespace std;

struct Splay{
	int tot,op;
	struct node{
		int ch[2],f,sz,cnt,val;
	}t[MAXN];
	void init(){//³õʼ»¯ 
		tot = op = 0;
	}
	int get(int rt){
		return (t[t[rt].f].ch[1] == rt);
	}
	int up(int rt){
		t[rt].sz = t[rt].cnt + t[t[rt].ch[0]].sz + t[t[rt].ch[1]].sz;
	}
	int rote(int rt){
	int d = get(rt);
	int ff = t[rt].f;
	if(ff == 0)return 0;
	int gg = t[ff].f;
	int cc = t[rt].ch[d ^ 1];
	if(gg)t[gg].ch[get(ff)] = rt;
	t[rt].f = gg;
	t[rt].ch[d ^ 1] = ff;
	if(ff)t[ff].f = rt;
	t[ff].ch[d] = cc;
	if(cc)t[cc].f = ff;
	up(ff);
	up(rt);
}
	int splay(int rt){
	int d;
	for(int f = t[rt].f ; (f = t[rt].f) ; rote(rt)){
		if(get(f) == get(rt))rote(f);
		else rote(rt);
	}
	op = rt;
}
	int add(int rt , int dx){
		if(!rt){
			rt = ++tot;
			op = rt;
			t[rt].sz = t[rt].cnt = 1;
			t[rt].val = dx;
			t[rt].f = 0;
			return 0;
		}
		int d;
		while(1){
			if(t[rt].val == dx){
				t[rt].cnt++;
				splay(rt);
				return 0;
			}
			d = (t[rt].val < dx);
			if(!t[rt].ch[d]){
				t[rt].ch[d] = ++tot;
				t[tot].cnt = t[tot].sz = 1;
				t[tot].val = dx;
				t[tot].f = rt;
				splay(tot);
				return 0;
			}
			rt = t[rt].ch[d];
		}	
	}
	int kth(int rt , int dx){
		int d;
		while(1){
			if(t[t[rt].ch[0]].sz >= dx)rt = t[rt].ch[0];
			else{
				dx -= t[t[rt].ch[0]].sz;
				if(t[rt].cnt >= dx){
				return t[rt].val;	
				}
				else dx -= t[rt].cnt , rt = t[rt].ch[1];	
			}
		}
	}
	int rank(int rt , int dx){
		int d;
		while(1){
			if(t[rt].val > dx)rt = t[rt].ch[0];
			else if(t[rt].val < dx)rt = t[rt].ch[1];
			else{
				splay(rt);return t[t[rt].ch[0]].sz;	
			} 
		}
	}
	int pre(int x){
		x = t[x].ch[1];
		while(t[x].ch[0])x = t[x].ch[0];
		return x; 
	}
	int nxt(int x){
		x = t[x].ch[0];
		while(t[x].ch[1])x = t[x].ch[1];
		return x;
	}
	int del(int dx){
		rank(op , dx);
		if(t[op].cnt > 1){
			t[op].cnt--;
			return 0;
		}
		if(!t[op].ch[0] && !t[op].ch[1]){
			op = 0;
			return 0;
		}
		if(!t[op].ch[0]){
			t[t[op].ch[1]].f = 0;
			op = t[op].ch[1];
			return 0;
		}
		if(!t[op].ch[1]){
			t[t[op].ch[0]].f = 0;
			op = t[op].ch[0];
			return 0;
		}
		splay(nxt(op));
		t[op].ch[1] = t[t[op].ch[1]].ch[1];
		t[t[op].ch[1]].f = op;
		up(op);
	}
}T;

int main(){
	T.init();
	int u;cin>>u;
	for(int i = 1 ; i <= u ; i++){
		int x,y;cin>>x>>y;
		if(x == 1)T.add(T.op , y);
		if(x == 2)T.del(y); 
		if(x == 3)cout<<T.rank(T.op , y) + 1<<endl;
		if(x == 4)cout<<T.kth(T.op , y)<<endl;
		if(x == 5){
			T.add(T.op , y);
			cout<<T.t[T.nxt(T.op)].val<<endl;
			T.del(y);	
		}
		if(x == 6){
			T.add(T.op , y);
			cout<<T.t[T.pre(T.op)].val<<endl;
			T.del(y);
		}	
	}
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章