codevs 4244 平衡树练习

Posted ZlycerQan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 4244 平衡树练习相关的知识,希望对你有一定的参考价值。

二次联通门 : codevs 4244 平衡树练习

 

Splay实测指针占用空间大约是数组的3倍, 且时间上也慢了差不多1s

 

数组版评测记录如下

 指针版评测记录如下

 

 

    以上数据仅限这一个题, 对于别的题,指针其实是比数组快的

  虽然这样。。。

  但是指针写起来就是看着顺眼。。。。

/*
    指针版
    
*/
#include <cstdio>
#include <cstdlib>

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    bool temp = false;
    while (word < \'0\' || word > \'9\')
    {
        if (word == \'-\')
            temp = true;
        word = getchar ();
    }
    while (word >= \'0\' && word <= \'9\')
    {
        now = now * 10 + word - \'0\';
        word = getchar ();
    }
    if (temp)
        now = -now;
}

struct Splay_Tree_Data
{
    Splay_Tree_Data *child[2];

    Splay_Tree_Data *father;

    int size, weigth;

    int key;
    inline void Updata ()
    {
        this->size = this->weigth;
        if (this->child[0] != NULL)
            this->size += this->child[0]->size;
        if (this->child[1] != NULL)
            this->size += this->child[1]->size;
    }
    
    inline int Get_Pos ()
    {
        return this->father->child[1] == this;
    }

    Splay_Tree_Data ()
    {
        child[0] = NULL;
        child[1] = NULL;
        size = weigth = 1;
        father = NULL;
        key = 0;
    }
};

Splay_Tree_Data *Root;

class Splay_Tree_Type
{
    private :
        
        inline void Rotate (Splay_Tree_Data *now)
        {
            Splay_Tree_Data *Father = now->father;
            if (now == NULL || Father == NULL)
                return ;
            int pos = now->Get_Pos () ^ 1;
            Father->child[pos ^ 1] = now->child[pos];
            if (now->child[pos])
                now->child[pos]->father = Father;
            if ((now->father = Father->father) != NULL)
                now->father->child[now->father->child[1] == Father] = now;
            Father->father = now;
            now->child[pos] = Father;
            Father->Updata ();
            now->Updata ();
            if (now->father == NULL)
                Root = now;
        }

        inline void Splay (Splay_Tree_Data *now, Splay_Tree_Data *to = NULL)
        {
            for (; now->father != to; Rotate (now))
                if (now->father->father != to)
                    Rotate (now->Get_Pos () == now->father->Get_Pos () ? now->father : now);
        }
        
    public :

        void Insert (int x)
        {
            Splay_Tree_Data *now = Root;
            if (Root == NULL)
            {
                Root = new Splay_Tree_Data;
                Root->key = x;
                Root->father = NULL;
                return ;
            }
            int pos;
            while (true)
            {
                if (now->key == x)
                {
                    now->size ++;
                    now->weigth ++;
                    Splay (now);
                    return ;
                }
                pos = x > now->key ? 1 : 0;
                if (now->child[pos] == NULL)
                {
                    now->child[pos] = new Splay_Tree_Data;
                    now->child[pos]->father = now;
                    now->child[pos]->key = x;
                    Splay (now->child[pos]);
                    return ;
                }
                now = now->child[pos];
            }
        }        
    
        bool Find (int x)
        {
            Splay_Tree_Data *now = Root;
            while (true)
            {
                if (x == now->key)
                    return true;
                else if (x < now->key && now->child[0] != NULL)
                    now = now->child[0];
                else if (x > now->key && now->child[1] != NULL)
                    now = now->child[1];
                else 
                    return false;
            }
        }
};

Splay_Tree_Type Tree;

int N, M;

int main (int argc, char *argv[])
{
    int x;
    for (read (N), read (M); N--; )
    {
        read (x);
        Tree.Insert (x);
    }
    for (; M--; )
    {
        read (x);
        if (Tree.Find (x))
            printf ("1 ");
        else
            printf ("0 ");
    }
    return 0;
}

 

 

 

 

 

/*
    数组版

    
*/
#include <cstdio>

#define Max 10000002

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    bool temp = false;
    while (word < \'0\' || word > \'9\')
    {
        if (word == \'-\')
            temp = true;
        word = getchar ();
    }
    while (word >= \'0\' && word <= \'9\')
    {
        now = now * 10 + word - \'0\';
        word = getchar ();
    }
    if (temp)
        now = -now;
}

class Splay_Tree_Type
{
    private :
    
        struct Splay_Tree_Date
        {
            int key;
            int father;
            int child[2];
        }    
        tree[Max];
        
        int Count;
        int Root;
        
        inline int Get_Son (int now)
        {
            return tree[tree[now].father].child[1] == now;
        }

        inline void Rotate (int now)
        {
            int father = tree[now].father;
            int Grand = tree[father].father;
            int pos = Get_Son (now);
            tree[father].child[pos] = tree[now].child[pos ^ 1];
            tree[tree[father].child[pos]].father = father;
            tree[now].child[pos ^ 1] = father;
            tree[father].father = now;
            tree[now].father = Grand;
            if (Grand)
                tree[Grand].child[tree[Grand].child[1] == father] = now;
        }
        
        inline void Splay (int now)
        {
            for (int father; father = tree[now].father; Rotate (now))
                if (tree[father].father)
                    Rotate (Get_Son (now) == Get_Son (father) ? father : now);
            Root = now;
        }
        
    public :
        
        void Insert (int x)
        {
            if (!Root)
            {
                Count++;
                tree[Count].key = x;
                Root = Count;
                return ;
            }
            int now = Root, father = 0;
            while (true)
            {
                if (tree[now].key == x)
                    return ;
                father = now;
                now = tree[now].child[x > tree[father].key];
                if (!now)
                {
                    Count++;
                    tree[Count].key = x;
                    tree[Count].father = father;
                    tree[father].child[x > tree[father].key] = Count;
                    Splay (Count);
                    return ;
                }
            }
        }
        
        int Find (int x)
        {
            int now = Root;
            while (true)
            {
                if (x == tree[now].key)
                    return 1;
                if (x < tree[now].key && tree[now].child[0])
                    now = tree[now].child[0];
                else if (x > tree[now].key && tree[now].child[1])
                    now = tree[now].child[1];
                else 
                    return 0;
                if (!now)
                    return 0;
            }
        }
};

Splay_Tree_Type Make;

int main (int argc, char *argv[])
{
    int N, M;
    read (N);
    read (M);
    int x;
    for (; N--; )
    {
        read (x);
        Make.Insert (x); 
    }
    for (; M--; )
    {
        read (x);
        printf ("%d ", Make.Find (x));
    }
    return 0;
}

 

以上是关于codevs 4244 平衡树练习的主要内容,如果未能解决你的问题,请参考以下文章

CodeVS 4927-线段树练习5

codevs1080线段树练习

codevs 4919 线段树练习4

线段树练习 codevs 1080

[Codevs] 线段树练习5

codevs 4927 线段树练习5