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;
}
时间: 2024-10-10 06:03:17

codevs 4244 平衡树练习的相关文章

codevs 4244 平衡树练习(STL)

/* STL */ #include<iostream> #include<cstdio> #include<map> using namespace std; map<int,int>a; int main() { int n,m,i,j,k; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { int s; scanf("%d",&s); a[s]=1;

codevs 4244 平衡树练习(STL)(set)

#include<iostream> #include<cstdio> #include<set> using namespace std; set<int>a; int main() { int n,m,i,j,k; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { int x; scanf("%d",&x); a.insert(x); } for(i=1

AC日记——平衡树练习 codevs 4244

4244 平衡树练习 思路: 有节操的人不用set也不用map: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 5000005 int n,m,ch[maxn][2],key[maxn],root; inline void in(int &now) { int if_

4244 平衡树练习

4244 平衡树练习 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 判断一些数字在一个数列中是否存在. 输入描述 Input Description 第一行输入两个正整数m和n. 第二行m个数字表示这个数列. 第三行n个数字表示需要判断的数字. 输出描述 Output Description 输出共一行n个0或1,0表示这个数字不存在,1表示存在. 样例输入 Sample Input 2 2 2 4 2 5 样例输

treap codevs 4543普通平衡树

#include<cstdio>#include<ctime>#include<cstdlib>struct shu{ int l,r,sum1,zhi,dui,sum2;}a[100006];int n,root,size,ans;void you(int &a1){ int t=a[a1].l; a[a1].l=a[t].r; a[t].r=a1; a[t].sum1=a[a1].sum1; a[a1].sum1=a[a[a1].l].sum1+a[a[a1

bzoj3224 Tyvj 1728 普通平衡树

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,

[ CodeVS冲杯之路 ] P2492

不充钱,你怎么AC? 题目:http://codevs.cn/problem/2492/ 在此先orz小胖子,教我怎么路径压缩链表,那么这样就可以在任意节点跳进链表啦(手动@LCF) 对于查询操作,直接树状数组(以下简称BIT)维护,修改操作就一个个暴力开方搞,再用差值单点更新BIT 不过这样会TLE,要加一点优化对不对,正如开头所说的路径压缩链表 路径压缩链表其实就是个并查集,在普通的链表里,删去两个连续的节点后会是下面这种情况,如删去2,3 当访问 2 的时候,会跳到3,但 3 已经删除了,

[CODEVS 1281] Xn数列

描述 给你6个数,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn http://codevs.cn/problem/1281/ 分析 比较裸的矩阵乘法题, 好久没做了, 写写思路 假设矩阵 A = { {a1, a2}, {a3, a4} }, B = { {b1, b2}, {b3, b4} }. 根据矩阵乘法的计算方法, 有 : A×B = { {a1b1+a2b2, a1b2+a2b4}, {a3b1+a4b3, a3b2+a4b4} }. 那

bzoj 3224: Tyvj 1728 普通平衡树.

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 15114  Solved: 6570[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为