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

SBT模版

时间:2015-04-14 23:17:41      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3378  Solved: 1379
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

 

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

 

Source

 
#include<cstdio>
#include<cstring>
#define N 2001000
using namespace std;
struct SBT
{
    int key,cnt;
    int l,r,size,sc;
}s[N];
int root,n,m;
void left_rotate(int &x)
{
    int y=s[x].r;
    s[x].r=s[y].l;
    s[y].l=x;
    s[y].size=s[x].size;
    s[y].sc=s[x].sc;
    s[x].size=s[s[x].l].size+s[s[x].r].size+1;
    s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt;
    x=y;
}
void right_rotate(int &x)
{
    int y=s[x].l;
    s[x].l=s[y].r;
    s[y].r=x;
    s[y].size=s[x].size;
    s[y].sc=s[x].sc;
    s[x].size=s[s[x].l].size+s[s[x].r].size+1;
    s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt;
    x=y;
}
void keep(int &x,int flag)
{
    s[x].size=s[s[x].l].size+s[s[x].r].size+1;
    s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt;
    if(!flag)
    {
        if(s[s[s[x].l].l].size>s[s[x].r].size)right_rotate(x);
        else if(s[s[s[x].l].r].size>s[s[x].r].size)left_rotate(s[x].l),right_rotate(x);
        else return ;
    }
    else
    {
        if(s[s[s[x].r].r].size>s[s[x].l].size)left_rotate(x);
        else if(s[s[s[x].r].l].size>s[s[x].l].size)right_rotate(s[x].r),left_rotate(x);
        else return ;
    }
    keep(s[x].l,0);
    keep(s[x].r,1);
    keep(x,0);
    keep(x,1);
}
void insert(int &x,int key)
{
    if(!x)
    {
        x=++n;
        s[x].size=s[x].sc=s[x].cnt=1;
        s[x].key=key;
    }
    else
    {
        if(key==s[x].key)s[x].cnt++,s[x].sc++;
        else if(key<s[x].key)insert(s[x].l,key),keep(x,0);
        else insert(s[x].r,key),keep(x,1);
    }
     
}
void del(int &x,int key)
{
    if(s[x].key==key)
    {
        if(s[x].cnt>1)s[x].cnt--,s[x].sc--;
        else if(!s[x].l&&!s[x].r)x=0;
        else if(!s[x].l*s[x].r)x=s[x].l+s[x].r;
        else if(s[s[x].l].size>s[s[x].r].size)right_rotate(x),del(s[x].r,key),keep(x,0);
        else left_rotate(x),del(s[x].l,key),keep(x,1);
    }
    else if(key<s[x].key)del(s[x].l,key),keep(x,1);
    else del(s[x].r,key),keep(x,0);
}
int find(int &x,int k)
{
    if(s[s[x].l].sc<k&&k<=s[s[x].l].sc+s[x].cnt)return s[x].key;
    if(k<=s[s[x].l].sc)return find(s[x].l,k);
    else return find(s[x].r,k-s[s[x].l].sc-s[x].cnt);
}
int rank(int &x,int key)
{
    if(s[x].key==key)return s[s[x].l].sc+1;
    if(key<s[x].key)return rank(s[x].l,key);
    else return rank(s[x].r,key)+s[x].cnt+s[s[x].l].sc;
}
int getmin()
{
    int x=root;
    for(;s[x].l;x=s[x].l);
    return s[x].key;
}
int getmax()
{
    int x=root;
    for(;s[x].r;x=s[x].r);
    return s[x].key;
}
int pred(int &x,int y,int key)
{
    if(!x)return y;
    if(key<=s[x].key)return pred(s[x].l,y,key);
    else return pred(s[x].r,x,key);
}
int succ(int &x,int y,int key)
{
    if(!x)return y;
    if(key<s[x].key)return succ(s[x].l,x,key);
    else return succ(s[x].r,y,key);
}
int main()
{
    int i,t,x;
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&t,&x);
        switch(t)
        {
            case 1:insert(root,x);break;
            case 2:del(root,x);break;
            case 3:printf("%d\n",rank(root,x));break;
            case 4:printf("%d\n",find(root,x));break;
            case 5:printf("%d\n",s[pred(root,0,x)].key);break;
            case 6:printf("%d\n",s[succ(root,0,x)].key);break;
        }
    }
    return 0;
}

  

SBT模版

标签:

原文地址:http://www.cnblogs.com/a972290869/p/4426306.html

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