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;
}

猜你喜欢

转载自www.cnblogs.com/wzl19981116/p/10087369.html