MLE求助!旋转Treap(尽管不主流)
查看原帖
MLE求助!旋转Treap(尽管不主流)
298402
cccyyylll888楼主2022/8/4 21:04
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int n;
int sz = 0;//整棵树大小 
int root = 0;
int key[100005],pri[100005];//key表示值,pri表示优先级
int ch[100005][2];//左子节点和右子节点 
int siz[100005];//子树大小(包括自己) 
int build(int k)//建点 
{
	int u = ++sz;
	key[u] = k;
	pri[u] = rand();
	ch[u][0] = ch[u][1] = 0;
	siz[u] = 1;
	return u;
}
void maintain(int u)//维护子树大小 
{
	siz[u] = siz[ch[u][0]] + siz[ch[u][1]] + 1;
}
void rotate(int &u,int d)//u为父节点,d为要旋转的子节点(引用)
{
	int v = ch[u][d];
	int p = ch[v][d^1];
	ch[u][d] = p; 
	maintain(u);
	ch[v][d^1] = u;
	maintain(v);
	u = v;//更新根节点 
}
void insert(int &u,int k)//插入点k 
{
	if(u == 0)
	{
		u = build(k);
		return;
	}
	int d = (k > key[u]);
	insert(ch[u][d],k);
	if(pri[ch[u][d]] > pri[u])
	rotate(u,d);
	maintain(u);
}
int rank1(int root,int k)//树里面有多少数严格小于k 
{
	int u = root;
	int ret = 0;
	while(u)
	{
		if(key[u] < k)
		{
			ret += siz[ch[u][0]] + 1;
			u = ch[u][1];
		}
		else
		{
			u = ch[u][0];
		}
	}
	return ret;
} 
int select(int root,int k)//第k小的 
{
	int u = root;
	while(u)
	{
		if(siz[ch[u][0]] == k) break;
		if(k < siz[ch[u][0]]) u = ch[u][0];
		else k -= (siz[ch[u][0]] + 1),u = ch[u][1];
	}
	return key[u];
 } 
void erase(int &u,int k)//删点 
{
	if(key[u] == k)
	{
		if(ch[u][0] == 0||ch[u][1] == 0)
		{
			u = ch[u][0] + ch[u][1];
		}
			int d = (pri[ch[u][1]] > pri[ch[u][0]]);
			rotate(u,d);
			erase(ch[u][d^1],k);	
	}
	else
	{
		int d = (k > key[u]);
		erase(ch[u][d],k);
	}
	if(u) maintain(u);
}
void dfs(int u)//输出中序遍历(即为从小到大) 
{
	if(ch[u][0])
	dfs(ch[u][0]);
	cout << key[u] << ' ';
	if(ch[u][1])
	dfs(ch[u][1]);
}
int main()
{
//	srand((int)time(NULL));
	cin >> n;
	root = 0;
	while(n--)
	{
		int op,x;
		cin >> op;
		if(op == 1)
		{
			cin >> x;
			insert(root,x);
		}
		if(op == 2)
		{
			cin >> x;
			erase(root,x);
		}
		if(op == 3)
		{
			cin >> x;
			cout << rank1(root,x) + 1 << endl;
		}
		if(op == 4)
		{
			cin >> x;
			cout << select(root,x-1) << endl;
		}
		if(op == 5)
		{
			cin >> x;
			cout << select(root,rank1(root,x)-1) << endl;
		}
		if(op == 6)
		{
			cin >> x;
			cout << select(root,rank1(root,x+1)) << endl;
		}
	}
	return 0;
} 
2022/8/4 21:04
加载中...