splay模板 (权值建树)

#include<stdio.h>    
#include<iostream>    
#include<algorithm>    
using namespace std;    
#define keytree ch[ch[root][1]][0]      
#define L(x) ch[x][0]      
#define R(x) ch[x][1]    
#define N 100010    
int ch[N][2],pre[N],cnt[N],size[N],key[N];    
int tot,root;    
int a[N],n;    
void newnode(int &u,int fa,int KEY)    
{    
    u=++tot;    
    ch[u][0]=ch[u][1]=0;    
    pre[u]=fa;cnt[u]=size[u]=1;    
    key[u]=KEY;    
}    
void up(int x)    
{      
     if(x)    
     {      
          size[x]=cnt[x];      
          if(ch[x][0])size[x]+=size[ch[x][0]];      
          if(ch[x][1])size[x]+=size[ch[x][1]];      
     }      
}    
void rotate(int u,int kind)//kind表示u在fa的哪一边    
{    
    int fa=pre[u];    
    ch[fa][kind]=ch[u][!kind];    
    pre[ch[u][!kind]]=fa;    
    if(pre[fa])ch[pre[fa]][ch[pre[fa]][1]==fa]=u;    
    pre[u]=pre[fa];    
    ch[u][!kind]=fa;    
    pre[fa]=u;    
    up(fa);up(u);    
}      
void splay(int u,int goal)    
{    
    int fa,kind;    
    while(pre[u]!=goal)    
    {    
        if(pre[pre[u]]==goal)    
        {    
            rotate(u,R(pre[u])==u);    
        }    
        else     
        {    
            fa=pre[u];    
            kind=R(pre[fa])==fa;    
            if(ch[fa][kind]!=u)//不在同一侧     
            {    
                rotate(u,!kind);    
                rotate(u,kind);    
            }    
            else     
            {    
                rotate(fa,kind);    
                rotate(u,kind);    
            }    
        }    
    }    
    up(u);    
    if(goal==0)root=u;    
}    
void insert(int v)    
{      
    if(root==0)     
    {    
        newnode(root,0,v);    
        return;    
    }      
    int now=root,fa=0;      
    while(1)    
    {      
        if(key[now]==v)    
        {      
            cnt[now]++;up(now);up(fa);splay(now,0);    
            break;      
        }      
        fa=now;      
        now=ch[now][key[now]<v];    
        if(now==0)    
        {    
            newnode(ch[fa][key[fa]<v],fa,v);    
            up(fa);splay(ch[fa][key[fa]<v],0);    
            break;    
        }    
    }    
}    
    
    
int getkth(int u,int k)//第k个键值的点的编号     
{    
    int s=size[L(u)]+cnt[u];    
    if(size[L(u)]<k&&k<=s) return u;    
    if(s-cnt[u]>=k) return getkth(L(u),k);    
    else return getkth(R(u),k-s);    
}      
int find(int u,int x)//查找键值为x的点的编号     
{                 
    if(key[u]==x)return u;    
    if(key[u]>x)    
    {    
        if(!L(u))return -1;    
        return find(L(u),x);    
    }    
    if(key[u]<x)    
    {    
        if(!R(u))return -1;    
        return find(R(u),x);    
    }    
}    
int getpre(int u)  
{  
	if(cnt[u]>=2)return u;
	u=L(u); 
    while(R(u))u=R(u);  
    return u;  
}  
int getnext(int u)  
{  
	if(cnt[u]>=2)return u;
    u=R(u);  
    while(L(u))u=L(u);  
    return u;  
}     
void del(int x)//删除编号为x的节点     
{    
    if(size[root]==1)  
    {  
        root=0;  
        return ;  
    }  
    if(cnt[x]>1)    
    {    
        cnt[x]--;    
        return ;    
    }    
    splay(x,0);    
    if(L(root))    
    {    
        if(!R(root))  
        {  
            pre[L(root)]=0;  
            root=L(root);  
            return ;  
        }  
        int p=getpre(x);    
        splay(p,root);    
        R(p)=R(root);    
        pre[R(root)]=p;    
        root=p;    
        pre[p]=0;    
        up(root);    
    }    
    else    
    {    
        root=R(root);    
        pre[root]=0;    
    }    
}     
//--------------------------------------------------基本操作     

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值