树板

突然发现没存过平衡树板子,趁这几天在复习平衡树,存一下还热乎的未封装版本

update 2022.2.24 上午更新了Splay板子,但是依然没封装。下午突然意识到Splay不是时刻平衡,所以每次操作都要Splay,但是上午的版本kth没有,所以又改了一下。

update 2022.2.27 顺手再存一个LCT板子,将平衡树板子更名为树板

$\rm FHQ\ Treap$
//12252024832524
#include <cstdio>
#include <cstring>
#include <algorithm>
#define TT template<typename T>
using namespace std; 

typedef long long LL;
const int MAXN = 100005;
const int MOD = 998244353;
int n;

LL Read()
{
	LL x = 0,f = 1;char c = getchar();
	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

int tot,rt;
struct FHQ_Treap
{
	int l,r,val,rd,siz;
}t[MAXN];
void up(int x){t[x].siz = t[t[x].l].siz + t[t[x].r].siz + 1;}
void split(int now,int val,int &x,int &y)
{
	if(!now) {x = y = 0;return;}
	else
	{
		if(t[now].val <= val) x = now,split(t[now].r,val,t[now].r,y);
		else y = now,split(t[now].l,val,x,t[now].l);
		up(now);
	}
}
int mge(int x,int y)
{
	if(!x || !y) return x|y;
	if(t[x].rd < t[y].rd) {t[x].r = mge(t[x].r,y);up(x);return x;}
	else {t[y].l = mge(x,t[y].l);up(y);return y;}
}
int newnode(int val)
{
	t[++tot] = {0,0,val,rand(),1};
	return tot;
}
int x,y,z;
void ins(int val)
{
//	printf("ins ins ins\n");
	split(rt,val-1,x,y);
//	printf("ins %d %d\n",x,y);
	rt = mge(x,mge(newnode(val),y));
}
void del(int val)
{
	split(rt,val,x,z);
	split(x,val-1,x,y);
	rt = mge(mge(x,mge(t[y].l,t[y].r)),z);
}
int qrk(int val)
{
	split(rt,val-1,x,y);
	int ret = t[x].siz+1;
	rt = mge(x,y);
	return ret;
}
int qval(int rk)
{
	x = rt;
	while(1)
	{
		if(t[t[x].l].siz+1 == rk) return t[x].val;
		else if(t[t[x].l].siz >= rk) x = t[x].l;
		else rk -= t[t[x].l].siz+1,x = t[x].r;
	}
}
int pre(int val)
{
	split(rt,val-1,x,y);
	int now = x;
	while(t[now].r) now = t[now].r;
	rt = mge(x,y);
	return t[now].val;
}
int suf(int val)
{
	split(rt,val,x,y);
	int now = y;
	while(t[now].l) now = t[now].l;
	rt = mge(x,y);
	return t[now].val;
}
void dfs(int now)
{
	if(!now) return;
//	printf("dfs %d %d %d %d\n",now,t[now].val,t[now].l,t[now].r);
	dfs(t[now].l);
	dfs(t[now].r);
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	srand(42523);
	for(int T = Read(); T ;-- T)
	{
		int opt = Read();
		if(opt == 1) ins(Read());
		else if(opt == 2) del(Read());
		else if(opt == 3) Put(qrk(Read()),'\n');
		else if(opt == 4) Put(qval(Read()),'\n');
		else if(opt == 5) Put(pre(Read()),'\n');
		else if(opt == 6) Put(suf(Read()),'\n');
	}
	return 0;
}
$\rm Splay$
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std; 

typedef long long LL;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;
int n;

LL Read()
{
	LL x = 0,f = 1;char c = getchar();
	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

#define lc t[x].ch[0]
#define rc t[x].ch[1]
int tot,rt;
struct node{
	int ch[2],f,siz,cnt,val;
}t[MAXN];
int newnode(int val,int fa){t[++tot] = node{0,0,fa,1,1,val};if(fa) t[fa].ch[val > t[fa].val] = tot;return tot;}
void up(int x){t[x].siz = t[lc].siz + t[rc].siz + t[x].cnt;}
bool ck(int x){return x == t[t[x].f].ch[1];}
void lk(int x,int fa,bool d){t[x].f = fa; if(fa) t[fa].ch[d] = x;}
void rotate(int x){
	int fa = t[x].f,d = ck(x);
	lk(t[x].ch[d^1],fa,d);
	lk(x,t[fa].f,ck(fa));
	lk(fa,x,d^1);
	up(fa); up(x);
}
void splay(int x,int to = 0){
	while(t[x].f ^ to){
		if(t[t[x].f].f ^ to){
			if(ck(x) == ck(t[x].f)) rotate(t[x].f);
			else rotate(x);
		}
		rotate(x);
	}
	if(!to) rt = x;//attention!
}
void ins(int val){
	int x = rt,fa = 0;
	while(x && t[x].val != val) fa = x,x = t[x].ch[val > t[x].val];
	if(x) ++t[x].cnt,++t[x].siz;
	else x = newnode(val,fa);
	splay(x);
}
void tort(int val){
	int x = rt;
	while(t[x].ch[val > t[x].val] && t[x].val != val) x = t[x].ch[val > t[x].val];
	splay(x);
}
int qrk(int val){
	tort(val);
	if(t[rt].val >= val) return t[t[rt].ch[0]].siz;
	else return t[t[rt].ch[0]].siz+t[rt].cnt;
}
int kth(int rk){
	int x = rt; ++rk;
	while(1){
		if(t[lc].siz >= rk) x = lc;
		else if(t[lc].siz + t[x].cnt >= rk) {splay(x);return x;}
		else rk -= t[lc].siz+t[x].cnt,x = rc;
	}
}
int pre(int val){return kth(qrk(val)-1);}
int suf(int val){return kth(qrk(val+1));}
void del(int val){
	int p = pre(val),s = suf(val);
	splay(p); splay(s,p);
	if(t[t[s].ch[0]].cnt > 1) --t[t[s].ch[0]].cnt,--t[t[s].ch[0]].siz;
	else t[s].ch[0] = 0;
	up(p);//new
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	ins(-INF); ins(INF);
	for(int T = Read(); T ;-- T){
		int opt = Read();
		if(opt == 1) ins(Read());
		else if(opt == 2) del(Read());
		else if(opt == 3) Put(qrk(Read()),'\n');
		else if(opt == 4) Put(t[kth(Read())].val,'\n');
		else if(opt == 5) Put(t[pre(Read())].val,'\n');
		else if(opt == 6) Put(t[suf(Read())].val,'\n');
	}
	return 0;
}
$\rm LCT$
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std; 

typedef long long LL;
const int MAXN = 100005;
int n,m;
int val[MAXN];

LL Read()
{
	LL x = 0,f = 1;char c = getchar();
	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

#define lc (t[x].ch[0])
#define rc (t[x].ch[1])
struct node{
	int ch[2],f,val;
	bool rev;
}t[MAXN];
bool ck(int x){return t[t[x].f].ch[1] == x;}
void lk(int x,int fa,bool d){t[x].f = fa; if(fa) t[fa].ch[d] = x;}
bool isroot(int x){return t[t[x].f].ch[0] != x && t[t[x].f].ch[1] != x;}
void calcrev(int x){if(!x) return; swap(lc,rc); t[x].rev ^= 1;}
void up(int x){t[x].val = t[lc].val ^ val[x] ^ t[rc].val;}
void down(int x){if(!t[x].rev) return; calcrev(lc); calcrev(rc); t[x].rev = 0;}
void rotate(int x){//这里没有down的原因是LCT的down是自上而下,因此Splay中的rotate执行前就已经down完了 
	int fa = t[x].f,d = ck(x);
	if(isroot(fa)) t[x].f = t[fa].f;
	else lk(x,t[fa].f,ck(fa));
	lk(t[x].ch[d^1],fa,d);
	lk(fa,x,d^1);
	up(fa); up(x); 
}
void downtag(int x){
	if(!isroot(x)) downtag(t[x].f);
	down(x);
}
void splay(int x){
	downtag(x);
	for(int y = t[x].f;!isroot(x);rotate(x),y = t[x].f)
		if(!isroot(y)) rotate(ck(x) == ck(y) ? y : x);
//	up(x);
}
void access(int x){
	for(int lst = 0; x ;lst = x,x = t[x].f)
		splay(x),rc = lst,up(x);
}
void makeroot(int x){
	access(x); splay(x); calcrev(x);
}
int findroot(int x){
	access(x); splay(x);
	while(lc) down(x),x = lc;
	splay(x); return x;
}
void split(int x,int y){
	makeroot(x); access(y); splay(y);
}
void link(int x,int y){
	if(findroot(x) == findroot(y)) return;
	makeroot(x); t[x].f = y;
}
void cut(int x,int y){
	if(findroot(x) ^ findroot(y)) return;
	makeroot(x); access(y); splay(x);
	if(t[y].f == x && !t[y].ch[0]) t[y].f = rc = 0,up(x);
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read(); m = Read();
	for(int i = 1;i <= n;++ i) t[i].val = val[i] = Read();
	while(m --> 0){
		int opt = Read(),u,v;
		if(!opt) u = Read(),v = Read(),split(u,v),Put(t[v].val,'\n');
		else if(opt == 1) link(Read(),Read());
		else if(opt == 2) cut(Read(),Read());
		else if(opt == 3) u = Read(),splay(u),val[u] = Read(),up(u);
	}
	return 0;
}
posted @ 2021-09-03 15:56  皮皮刘  阅读(44)  评论(0编辑  收藏  举报