码迷,mamicode.com
首页 > 其他好文 > 详细

Splay模板

时间:2019-06-14 12:26:45      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:没有   fine   ace   string   ast   ring   next   clu   using   

#include<iostream>
#include<cstring>
#include<cstdio>
#define Reg register
#define INF 0x7ffffff
using namespace std;
int size,n,root;
struct Tree {int ch[2],val,cnt,size,fat;} tree[1000050];
int GetFat(int x)
{
    return tree[tree[x].fat].ch[1]==x;
}
void Update(int x)
{
    tree[x].size=tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+tree[x].cnt;
    return;
}
void Rotate(int x)
{
    int y=tree[x].fat;
    int z=tree[y].fat;
    int k=GetFat(x);    //先定义k 
    //x.rch-->y.lch
    tree[y].ch[GetFat(x)]=tree[x].ch[k^1];
    tree[tree[y].ch[k]].fat=y;
    //x-->z
    tree[z].ch[GetFat(y)]=x;
    tree[x].fat=z;
    //y-->x
    tree[x].ch[k^1]=y;
    tree[y].fat=x;
    Update(y); Update(x);
    //注意顺序 
    return;
}
void Splay(int x,int goal)
{
    while(tree[x].fat!=goal)
    {
        int y=tree[x].fat,z=tree[y].fat;
        if(z!=goal)
        {
            if(GetFat(y)==GetFat(x)) Rotate(y);
            else Rotate(x);
        }
        Rotate(x);
    }
    if(goal==0) root=x;
    return;
}
void Find(int num)
{
    int k=root;
    while(tree[k].ch[num>tree[k].val]&&num!=tree[k].val)
        k=tree[k].ch[num>tree[k].val];
    Splay(k,0);
    return;
}
int GetPre(int num)
{
    Find(num);
    if(tree[root].val<num) return root;
    int k=tree[root].ch[0];
    while(tree[k].ch[1]) k=tree[k].ch[1];
    return k;
}
int GetNext(int num)
{
    Find(num);
    if(tree[root].val>num) return root;
    int k=tree[root].ch[1];
    while(tree[k].ch[0]) k=tree[k].ch[0];
    return k;
}
void Insert(int num)
{
    int k=root,p=0;
    //Get position
    while(k&&tree[k].val!=num)
    {
        p=k;                              //father
        k=tree[k].ch[num>tree[k].val];
    }
    if(k) ++tree[k].cnt;
    else
    {
        k=++size;
        if(p) tree[p].ch[num>tree[p].val]=k;  //接上
        tree[k].ch[0]=tree[k].ch[1]=0;
        tree[k].fat=p; tree[k].val=num;
        tree[k].cnt=tree[k].size=1;
    }
    Splay(k,0); //update & 转到根
    return;
}
void Delete(int num)
{
    int last=GetPre(num),next=GetNext(num);
    Splay(last,0); Splay(next,root);
    //root‘s rch‘s lch =num & 没有儿子 
    int del=tree[next].ch[0];
    if(tree[del].cnt>1)   //直接减 
    {
        --tree[del].cnt;
        Splay(del,0);
    }
    else tree[next].ch[0]=0;
    return; 
}
int GetVal(int num)
{
    int k=root;
    while(1)
    {
        if(tree[k].ch[0]&&num<=tree[tree[k].ch[0]].size)  //在左儿子 
            k=tree[k].ch[0];
        else if(num>tree[tree[k].ch[0]].size+tree[k].cnt) //在右儿子
        {
            num-=(tree[tree[k].ch[0]].size+tree[k].cnt);  //注意顺序 
            k=tree[k].ch[1];
        }
        else return k;  //在根节点 
    }
}
int GetRank(int num)
{
    Find(num);
    return tree[tree[root].ch[0]].size;   //之前Insert了1个极小数 
}
int main()
{
    scanf("%d",&n);
    Insert(INF);
    Insert(-INF);  //为了减少时间 
    for(Reg int i=1,x,y;i<=n;++i)
    {
        scanf("%d%d",&x,&y);
        if(x==1) Insert(y);
        else if(x==2) Delete(y);
        else if(x==3) printf("%d\n",GetRank(y));
        else if(x==4) printf("%d\n",tree[GetVal(y+1)].val); //排除极小值 
        else if(x==5) printf("%d\n",tree[GetPre(y)].val);
        else printf("%d\n",tree[GetNext(y)].val);
    }
    return 0; 
}

 

Splay模板

标签:没有   fine   ace   string   ast   ring   next   clu   using   

原文地址:https://www.cnblogs.com/Milk-Feng/p/11022548.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!