FHQ Treap 板子求助
查看原帖
FHQ Treap 板子求助
351249
qige_mingzi楼主2023/10/27 07:41

RT,WA on #4-13,

评测记录

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
const int maxn = 1e5+100;
int val[maxn],key[maxn],siz[maxn],ls[maxn],rs[maxn],cnt;
int root;
mt19937 ran(time(0));
void update(int x){
	siz[x] = siz[ls[x]]+siz[rs[x]]+1;
}
void split(int now,int v,int &x,int &y){//x为左子树的根,y为右子树的根。 
	if(!now){
		x = 0,y = 0;
		return;
	}
	if(val[now] <= v){
		x = now;
		split(rs[now],v,rs[now],y);
	}
	else{
		y = now;
		split(ls[now],v,x,ls[now]);
	}
	update(now);
}
int merge(int x,int y){//返回值为合并后根节点的编号 
	if(!x||!y){
		return x+y;//x不存在返回y,y不存在同理 
	}
	if(key[x] < key[y]){//小根堆 
		rs[x] = merge(rs[x],y);
		update(x);
		return x;
	}
	else{
		ls[y] = merge(x,ls[y]);//注意这里由于x恒小于y,所以有关于x的全部传为x,有关y的全部传为y(不要传反了!) 
		update(y);
		return y;
	}
}
int create(int x){
	val[++cnt] = x;
	key[cnt] = ran();
	siz[cnt] = 1;
	return cnt;
}
int x,y,z;
void insert(int v){
	split(root,v,x,y);
	root = merge(merge(x,create(v)),y);
}
void del(int v){
	split(root,v-1,x,z);
	split(x,v-1,x,y);
	y = merge(ls[y],rs[y]);
	root = merge(merge(x,y),z);
}
int ask_rank(int v){
	int ans = 0;
	split(root,v-1,x,y);
	ans = siz[x];
	root = merge(x,y);
	return ans+1;
}
int ra(int r){
	int now = root;
	while(now){
		if(siz[ls[now]]+1 == r){
			break;
		}
		else if(siz[ls[now]]+1 > r){
			now = ls[now];
		}
		else{
			now = rs[now];
		}
	}
	return val[now];
}
int pre(int v){
	split(root,v-1,x,y);
	int now = x;
	int ans = 0;
	while(now){
		ans = now;
		now = rs[now];
	}
	root = merge(x,y);
	return val[ans];
}
int nex(int v){
	split(root,v,x,y);
	int now = y;
	int ans = 0;
	while(now){
		ans = now;
		now = ls[now];
	}
	root = merge(x,y);
	return val[ans];
}
signed main()
{
 	freopen("P3369_5.in","r",stdin);
	//freopen(".out","w",stdout);
	cin >> n;
	int opt,rr;
	for(int i = 1;i <= n;i++){
		scanf("%lld%lld",&opt,&rr);
		if(opt == 1){
			insert(rr);
		}
		else if(opt == 2){
			del(rr);
		}
		else if(opt == 3){
			cout << ask_rank(rr) << '\n';
		}
		else if(opt == 4){
			cout << ra(rr) << '\n';
		}
		else if(opt == 5){
			cout << pre(rr) << '\n';
		}
		else{
			cout << nex(rr) << '\n';
		}
	}
	return 0;
}
/*
Author: qige_mingzi
Start thinking at
Start coding at
Finish coding at
Finish debugging at
*/

2023/10/27 07:41
加载中...