hihocoder 1329 splay 伸展树

自己写的伸展树 用指针实现

删除那块还不是很理解

三个操作使树更加平衡的原理还有有待加深理解

有待加强

#include <bits/stdc++.h>
#define N 101000
#define FREI freopen("in.txt","r",stdin)
#define FREO freopen("out.txt","w",stdout)
#define Mem(a,b) memset(a,b,sizeof(a))
#define lson root<<1
#define rson root<<1|1
#define Mid int mid=(l+r)>>1
#define inf 0x3f3f3f3f
using namespace std;
int res;
struct node {
    int num,weight;
    node *left;
    node *right;
    node *father;
};
node *root,*ansp;
node* Insert(node *&p,node *father,int val) {
    if(p==0) {
        p=(node*)malloc(sizeof(node));
        p->num=val;
        p->left=0;
        p->right=0;
        p->father=father;
        return p;
    }
    if(val<p->num)
        return Insert(p->left,p,val);
    if(val>p->num)
        return Insert(p->right,p,val);
    return 0;
}
void left_rotate(node *x) {
    node *p=x->father;
    if(p==0)
        return;
    x->father=p->father;
    if(x->father==0) root=x;
    if(p->father!=0){
        if(p->father->left==p)
            p->father->left=x;
        else
            p->father->right=x;
    }
    p->right=x->left;
    if(x->left!=0) x->left->father=p;
    x->left=p;
    p->father=x;
}
void right_rotate(node *x) {
    node *p=x->father;
    if(p==0)
        return;
    x->father=p->father;
    if(x->father==0) root=x;
    if(p->father!=0){
        if(p->father->left==p)
            p->father->left=x;
        else
            p->father->right=x;
    }
    p->left=x->right;
    if(x->right!=0) x->right->father=p;
    x->right=p;
    p->father=x;
}
void splay(node *x,node *y){
    while(x->father!=y){
        node *p=x->father;
        if(p->father==y){
            if(p->left==x)
                right_rotate(x);
            else
                left_rotate(x);
        }
        else{
            node *g=p->father;
            if(g->left==p){
                if(p->left==x){
                    right_rotate(p);
                    right_rotate(x);
                }
                else{
                    left_rotate(x);
                    right_rotate(x);
                }
            }
            else{
                if(p->right==x){
                    left_rotate(p);
                    left_rotate(x);
                }
                else{
                    right_rotate(x);
                    left_rotate(x);
                }
            }
        }
    }
}
void Find(node *p,int val) {
    if(p==0)
        return;
    if(p->num<=val) {
        if(res<p->num){
            res=p->num;
            ansp=p;
        }
    }
    if(val<p->num)
        Find(p->left,val);
    if(val>p->num)
        Find(p->right,val);
}
node* Findpre(node *key){
    node *p=key->left;
    while(p->right)
        p=p->right;
    return p;
}
node* Findnext(node *key){
    node *p=key->right;
    while(p->left)
        p=p->left;
    return p;
}
node* Findkey(node *p,int val){
    res=-inf;
    Find(p,val);
    splay(ansp,0);
    return ansp;
}
void Insertkey(node *p,int val){
    node *tmp=Insert(p,0,val);
    if(tmp!=0) splay(tmp,0);
}
void Delete(node *a,node *b){
    node *pre=Findpre(a);
    node *next=Findnext(b);
    splay(pre,0);
    splay(next,pre);
    next->left=0;
}
int main() {
    //FREI;
    //FREO;
    int n;
    scanf("%d",&n);
    root=0;
    Insert(root,0,inf);
    Insert(root,0,-inf);
    for(int i=1; i<=n; i++) {
        char x;
        scanf("\n%c",&x);
        int val;
        if(x=='I'){
            scanf("%d",&val);
            Insertkey(root,val);
        }
        if(x=='Q'){
            scanf("%d",&val);
            Findkey(root,val);
            printf("%d\n",res);
        }
        if(x=='D'){
            int l,r;
            scanf("%d%d",&l,&r);
            Insertkey(root,l);
            Insertkey(root,r);
            node *a=Findkey(root,l);
            node *b=Findkey(root,r);
            Delete(a,b);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值