社区讨论

treap树求调 7分

P3369【模板】普通平衡树参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lwucnptr
此快照首次捕获于
2024/05/31 15:15
2 年前
此快照最后确认于
2024/05/31 18:55
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e5+5;
const int INF = 0x3f3f3f3f;
#define int long long 
struct node{
	int l,r;
	int val,pri;
	int cnt,size;
}tree[maxn];
int n,tot,root;
int NEW(int val){
	tree[++tot].val=val;
	tree[tot].pri=rand();
	tree[tot].cnt=tree[tot].size=1;
	tree[tot].l=tree[tot].r=0;
	return tot;
}

void update(int p){
	tree[p].size=tree[tree[p].l].size+tree[tree[p].r].size+tree[p].cnt;
}

void build(){
	NEW(-INF); NEW(INF);
	root=1,tree[1].r=2;
	update(root);
}

void zig(int &p){
	int q=tree[p].l;
	tree[p].l=tree[q].r;
	tree[q].r=p;
	p=q;
	update(tree[p].r);
	update(p);
}

void zag(int &p){
	int q=tree[p].r;
	tree[p].r=tree[q].l;
	tree[q].l=p;
	p=q;
	update(tree[p].l);
	update(p);
}

void inst(int &p,int val){
	if(!p){
		p=NEW(val);
		return;
	}
	if(val==tree[p].val){
		tree[p].cnt++,update(p);
		return;
	}
	if(val<tree[p].val){
		inst(tree[p].l,val);
		if(tree[p].pri<tree[tree[p].l].pri) zig(p);		
	}
	else{
		inst(tree[p].r,val);
		if(tree[p].pri<tree[tree[p].r].pri) zag(p);
	}
	update(p);
}

void del(int &p,int val){
	if(!p) return;
	if(val==tree[p].val){
		if(tree[p].cnt>1){
			tree[p].cnt--; update(p);
			return;
		}
		if(tree[p].l || tree[p].r){
			if(!tree[p].r || tree[tree[p].l].pri>tree[tree[p].r].pri){
				zig(p);
				del(tree[p].r,val);
			}
			else{
				zag(p);
				del(tree[p].r,val);
			}
			update(p);
		}
	}
	else{
		p=0;
		return ;
	}
	if(val<tree[p].val){
		del(tree[p].l,val);
	}
	else{
		del(tree[p].r,val);
	}
	update(p);
}

int findrank(int p,int val){
	if(!p) return 0;
	if(val==tree[p].val) return tree[tree[p].l].size+1;
	if(val<tree[p].val) return findrank(tree[p].l,val);
	return findrank(tree[p].r,val-tree[tree[p].l].size-tree[p].cnt);
}

int findval(int p,int rank){
	if(!p) return INF;
	if(tree[tree[p].l].size>=rank) return findval(tree[p].l,rank);
	if(tree[tree[p].l].size+tree[p].cnt>=rank) return tree[p].val;
	return findval(tree[p].r,rank-tree[tree[p].l].size-tree[p].cnt);
}

int findmin(int val){
	int ans=1;
	int p=root;
	while(p){
		if(val==tree[p].val){
			if(tree[p].l>0){
				p=tree[p].l;
				while(tree[p].r>0) p=tree[p].r;
				ans=p;
			}
			break;
		}
		if(tree[p].val<val&&tree[p].val>tree[ans].val) ans=p;
		p=val<tree[p].val?tree[p].l:tree[p].r;
	}
	return tree[ans].val;
}

int findmax(int val){
	int ans=2;
	int p=root;
	while(p){
		if(val==tree[p].val){
			if(tree[p].r>0){
				p=tree[p].r;
				while(tree[p].l>0) p=tree[p].l;
				ans=p;
			}
			break;
		}
		if(tree[p].val<val&&tree[p].val>tree[ans].val) ans=p;
		p=val<tree[p].val?tree[p].l:tree[p].r;
	}
	return tree[ans].val;
}

signed main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	build();
	for(int i=1;i<=n;i++){
		int op,x;
		cin>>op>>x;
		switch(op){
			case 1:inst(root,x); break;
			case 2:del(root,x); break;
			case 3:printf("%lld\n",findrank(root,x)); break;
			case 4:printf("%lld\n",findval(root,x)); break;
			case 5:printf("%lld\n",findmin(x)); break;
			case 6:printf("%lld\n",findmax(x)); break;
		}
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...