10.1jihe

两种操作,1是加入数字,二是找最接近的
用set或者平衡二叉树就好了
只写了二叉树的,套版子就好

#include<bits/stdc++.h>
#define sf scanf
#define scf(x) scanf("%d",&x)
#define scff(x,y) scanf("%d%d",&x,&y)
#define scfff(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define pf printf
#define prf(x) printf("%d\n",x)
#define mm(x,b) memset((x),(b),sizeof(x))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
typedef long long ll;
const ll mod=1e9+100;
const double eps=1e-8;
using namespace std;
const double pi=acos(-1.0);
const int inf=0xfffffff;
const int N=1e5+7;
struct node
{
	int lc,rc,h,v;
}tree[N];
int pos=0,x1,x2,x3,root;
int right_rotate(int r)//zig右旋
{
	int t = tree[r].lc;
	tree[r].lc = tree[t].rc;
	tree[t].rc = r;
	tree[r].h = max(tree[tree[r].lc].h,tree[tree[r].rc].h)+1;
	tree[t].h = max(tree[tree[t].lc].h,tree[tree[t].rc].h)+1;
	return t;
}
int left_rotate(int r)//zag左旋
{
	int t = tree[r].rc;
	tree[r].rc = tree[t].lc;
	tree[t].lc = r;
	tree[r].h = max(tree[tree[r].lc].h,tree[tree[r].rc].h)+1;
	tree[t].h = max(tree[tree[t].lc].h,tree[tree[t].rc].h)+1;
	return t;
}
int right_left_rotate(int r)//zigzag双旋
{
	tree[r].rc = right_rotate(tree[r].rc);
	return left_rotate(r);
}
int left_right_rotate(int r)//zagzig双旋
{
	tree[r].lc = left_rotate(tree[r].lc);
	return right_rotate(r);
}
void maintain(int &r)
{
	if(tree[tree[r].lc].h == tree[tree[r].rc].h+2)//左子树高了
	{
		int t = tree[r].lc;
		if(tree[tree[t].lc].h == tree[tree[r].rc].h+1) r = right_rotate(r);//左子树的左儿子,对应第一种情况
		else if(tree[tree[t].rc].h == tree[tree[r].rc].h+1) r = left_right_rotate(r);	
	}
	else if(tree[tree[r].rc].h == tree[tree[r].lc].h+2)//右子树高了
	{
		int t = tree[r].rc;
		if(tree[tree[t].rc].h == tree[tree[r].lc].h+1) r = left_rotate(r);//右子树的右儿子,对应第四种情况
		else if(tree[tree[t].lc].h == tree[tree[r].lc].h+1) r = right_left_rotate(r);
	}
	tree[r].h = max(tree[tree[r].lc].h,tree[tree[r].rc].h)+1;//高度更新
}
void prem(int x,int r)//找x的前驱
{
    if(r == 0) return;
    if(tree[r].v < x)
    {
        x1 = tree[r].v;
        prem(x,tree[r].rc);
    }
    else prem(x,tree[r].lc);
}
void nexm(int x,int r)//找x后一个数字
{
    if(r == 0) return;
    if(tree[r].v > x)
    {
        x2 = tree[r].v;
        nexm(x,tree[r].lc);
    }
    else nexm(x,tree[r].rc);
}
void find(int x,int r)//找到x
{
	if(r==0) return;
	if(tree[r].v ==x)
	{
		x3=x;
		return ;
	}
	if(tree[r].v > x)
        find(x,tree[r].lc);
    else 
		find(x,tree[r].rc);
}
int insert(int r,int x)
{
	if(r == 0)//找到一个空的节点,赋值
	{
		tree[++pos].h = 1;//高度初始化
		tree[pos].v = x;
		return pos;
	}
	if(x < tree[r].v) tree[r].lc = insert(tree[r].lc,x);//插入的数小于根节点,因此在它的左子树插入
	else if(x > tree[r].v) tree[r].rc = insert(tree[r].rc,x);
	maintain(r);//维持节点r的平衡
	return r;//返回新的根节点
}
int main()
{
	int n,aa,x;scf(n);
	while(n--)
	{
		scff(aa,x);
		if(aa==1)
			root=insert(root,x);	
		else
		{
				x1=x2=x3=0;
				prem(x,root);
				nexm(x,root);
				find(x,root);
			//	cout<<x1<<" "<<x2<<endl;
				if(x3)
					prf(x3);
				else if(x1==0&&x2==0)
					pf("Empty!\n");
				else if(x1==0)
					prf(x2);
				else if(x2==0)
					prf(x1);
				else
				{
					if(x-x1==x2-x)
						pf("%d %d\n",x1,x2);
					else
					{
						if(x-x1<x2-x)
							prf(x1);
						else
							prf(x2);
					}
				}
		}
	}
	return 0;
}
posted @ 2018-12-08 13:05  一无所知小白龙  阅读(261)  评论(0编辑  收藏  举报