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

BZOJ 题目3224: Tyvj 1728 普通平衡树(SBT)

时间:2015-08-15 18:27:48      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 4350  Solved: 1769
[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

平衡树

好吧,,从昨天就一直改这个代码,,,右旋的时候size少加了1,,,re一片啊,主要这个是有重的。

ac代码

/**************************************************************
    Problem: 3224
    User: kxh1995
    Language: C++
    Result: Accepted
    Time:484 ms
    Memory:47708 kb
****************************************************************/
 
#include<stdio.h>
#include<string.h>
#define min(a,b) (a>b?b:a)
#define INF 0xfffffff
struct s    
{    
    int key,left,right,size,sc,cnt;    
}tree[2001000];    
int top,root;    
void left_rot(int &x)  
{    
    int y=tree[x].right;    
    tree[x].right=tree[y].left;    
    tree[y].left=x;
    tree[y].size=tree[x].size;
    tree[y].sc=tree[x].sc;
    tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
    tree[x].sc=tree[tree[x].left].sc+tree[tree[x].right].sc+tree[x].cnt;
    x=y;    
}    
void right_rot(int &x)  
{    
    int y=tree[x].left;    
    tree[x].left=tree[y].right;    
    tree[y].right=x;    
    tree[y].size=tree[x].size; 
    tree[y].sc=tree[x].sc;
    tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
    tree[x].sc=tree[tree[x].left].sc+tree[tree[x].right].sc+tree[x].cnt;
    x=y;    
}    
void maintain(int &x,bool flag)     
{    
    tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
    tree[x].sc=tree[tree[x].left].sc+tree[tree[x].right].sc+tree[x].cnt;
    if(flag==false)  
    {    
        if(tree[tree[tree[x].left].left].size>tree[tree[x].right].size)  
            right_rot(x);    
        else
            if(tree[tree[tree[x].left].right].size>tree[tree[x].right].size)    
            {    
                left_rot(tree[x].left);    
                right_rot(x);       
            }    
            else
                return;    
    }    
    else
    {    
        if(tree[tree[tree[x].right].right].size>tree[tree[x].left].size)  
            left_rot(x);    
        else
            if(tree[tree[tree[x].right].left].size>tree[tree[x].left].size)  
            {    
                right_rot(tree[x].right);    
                left_rot(x);    
            }    
            else
                return;    
    }    
    maintain(tree[x].left,false);    
    maintain(tree[x].right,true);    
    maintain(x,true);    
    maintain(x,false);    
}    
void insert(int &x,int key)    
{    
    if(x==0)    
    {    
        x=++top;    
    //  tree[x].left=0;    
      //  tree[x].right=0;    
        tree[x].size=tree[x].sc=tree[x].cnt=1;
        tree[x].key=key;    
    }    
    else
    {    
       // tree[x].size++;
        if(tree[x].key==key)
        {
            tree[x].cnt++;
            tree[x].sc++;
        }
        else
            if(key<tree[x].key) 
            {
                insert(tree[x].left,key);
                maintain(x,false);
            }
            else
            {
                insert(tree[x].right,key);
                maintain(x,true);
            }
        maintain(x,key>=tree[x].key);    
    }    
}
void remove(int &x,int key)
{
    if(tree[x].key==key)
    {
        if(tree[x].cnt>1)
        {
            tree[x].cnt--;
            tree[x].sc--;
        }
        else
            if(!tree[x].left&&!tree[x].right)
            {
                x=0;
            }
            else
                if(!(tree[x].left*tree[x].right))
                    x=tree[x].left+tree[x].right;
                else
                    if(tree[tree[x].left].size>tree[tree[x].right].size)
                    {
                        right_rot(x);
                        remove(tree[x].right,key);
                        maintain(x,false);
                    }
                    else
                    {
                        left_rot(x);
                        remove(tree[x].left,key);
                        maintain(x,true);
                    }
    }
    else
        if(key<tree[x].key)
        {
            remove(tree[x].left,key);
            maintain(x,true);
        }
        else
        {
            remove(tree[x].right,key);
            maintain(x,false);
        }
}
int getmin(int x)    
{    
    while(tree[x].left)    
        x=tree[x].left;    
    return tree[x].key;    
}    
int getmax(int x)    
{    
    while(tree[x].right)    
        x=tree[x].right;    
    return tree[x].key;    
}    
int pred(int &x,int y,int key)    
{    
    if(x==0)  
    {  
        return tree[y].key;
    }  
    if(key>tree[x].key)    
        return pred(tree[x].right,x,key);    
    else
        return pred(tree[x].left,y,key);    
}    
int succ(int &x,int y,int key)    
{    
    if(x==0)  
    {  
        return tree[y].key;
    }  
    if(key<tree[x].key)    
        return succ(tree[x].left,x,key);    
    else
        return succ(tree[x].right,y,key);    
}
int get_min_k(int &x,int k)//选第k小的数      
{    
    if(tree[tree[x].left].sc<k&&k<=tree[tree[x].left].sc+tree[x].cnt)
        return tree[x].key;
    if(k<=tree[tree[x].left].sc)
        return get_min_k(tree[x].left,k);
    else
        return get_min_k(tree[x].right,k-tree[tree[x].left].sc-tree[x].cnt);
}  
int rank(int &x,int key)//key排第几   
{  
    if(key<tree[x].key)  
    {  
        return rank(tree[x].left,key);  
    }  
    else
        if(key>tree[x].key)  
            return rank(tree[x].right,key)+tree[tree[x].left].sc+tree[x].cnt;  
        else
            return tree[tree[x].left].sc+1;  
}  
int main()
{
    int n,m;
    while(scanf("%d",&n)!=EOF)
    {
        int i;
        top=root=0;
        while(n--)
        {
            int op,x;
            scanf("%d%d",&op,&x);
            if(op==1)
                insert(root,x);
            else
                if(op==2)
                {
                    remove(root,x);
                }
                else
                    if(op==3)
                    {
                        printf("%d\n",rank(root,x));
                    }
                    else
                        if(op==4)
                        {
                            printf("%d\n",get_min_k(root,x));
                        }
                        else
                            if(op==5)
                            {
                                printf("%d\n",pred(root,0,x));
                            }
                            else
                                printf("%d\n",succ(root,0,x));
        }
    }
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

BZOJ 题目3224: Tyvj 1728 普通平衡树(SBT)

标签:

原文地址:http://blog.csdn.net/yu_ch_sh/article/details/47683115

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