• bzoj3224 Tyvj 1728 普通平衡树


    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 18119  Solved: 7981
    [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.每个数的数据范围:[-2e9,2e9]

    Source

    分析:splay模板题,只是需要注意可能有多个相同的数,需要记录值为x的数有多少个.
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 200010;
    int n,m,sizee[maxn],pos[maxn],tot,root,a[maxn];
    
    struct node
    {
        int fa,left,right,v,cnt;
    }e[maxn];
    
    void update(int x)
    {
        sizee[x] = e[x].cnt;
        if (e[x].left != -1)
            sizee[x] += sizee[e[x].left];
        if (e[x].right != -1)
            sizee[x] += sizee[e[x].right];
    }
    
    int getsize(int x)
    {
        if (x == -1)
            return 0;
        return sizee[x];
    }
    
    void turnr(int x)
    {
        int y = e[x].fa;
        int z = e[y].fa;
        e[y].left = e[x].right;
        if (e[x].right != -1)
            e[e[x].right].fa = y;
        e[x].fa = z;
        if (z != -1)
        {
            if (e[z].left == y)
                e[z].left = x;
            else
                e[z].right = x;
        }
        e[x].right = y;
        e[y].fa = x;
        update(y);
        update(x);
    }
    
    void turnl(int x)
    {
        int y = e[x].fa;
        int z = e[y].fa;
        e[y].right = e[x].left;
        if (e[x].left != -1)
            e[e[x].left].fa = y;
        e[x].fa = z;
        if (z != -1)
        {
            if (e[z].left == y)
                e[z].left = x;
            else
                e[z].right = x;
        }
        e[x].left = y;
        e[y].fa = x;
        update(y);
        update(x);
    }
    
    void splay(int x)
    {
        while (e[x].fa != -1)
        {
            int y = e[x].fa;
            int z = e[y].fa;
            if (z == -1)
            {
                if (x == e[y].left)
                    turnr(x);
                else
                    turnl(x);
            }
            else
            {
                if (e[z].left == y && e[y].left == x)
                {
                    turnr(y);
                    turnr(x);
                }
                else
                {
                    if (e[z].right == y && e[y].right == x)
                    {
                        turnl(y);
                        turnl(x);
                    }
                    else
                    {
                        if (e[z].left == y && e[y].right == x)
                        {
                            turnl(x);
                            turnr(x);
                        }
                        else
                        {
                                turnr(x);
                                turnl(x);
                        }
                    }
                }
            }
        }
        root = x;
    }
    
    int find(int x)
    {
        int p = root;
        while (p != -1)
        {
            if (e[p].v == x)
                return p;
            if (x < e[p].v)
                p = e[p].left;
            else
                p = e[p].right;
        }
        return p;
    }
    
    void del(int x)
    {
        int p = find(x);
        splay(p);
        if (e[p].cnt > 1)
            {
                e[p].cnt--;
                update(p);
                return;
            }
        if (e[p].left == -1 && e[p].right == -1)
        {
            root = -1;
            return;
        }
        if (e[p].left == -1)
        {
            root = e[p].right;
            e[e[p].right].fa = -1;
            return;
        }
        if (e[p].right == -1)
        {
            root = e[p].left;
            e[e[p].left].fa = -1;
            return;
        }
        int j = e[p].left;
        while (e[j].right != -1)
            j = e[j].right;
        splay(j);
        e[j].right = e[p].right;
        e[e[p].right].fa = j;
        update(j);
    }
    
    void insert(int x,int y)
    {
        if (e[y].v == x)
        {
            e[y].cnt++;
            splay(y);
            update(y);
            return;
        }
        if (x < e[y].v)
        {
            if (e[y].left == -1)
            {
                e[y].left = ++tot;
                e[tot].left = e[tot].right = -1;
                e[tot].v = x;
                e[tot].fa = y;
                e[tot].cnt = 1;
                sizee[tot] = 1;
                return;
            }
            else
                insert(x,e[y].left);
        }
        else
        {
            if (e[y].right == -1)
            {
                e[y].right = ++tot;
                e[tot].left = e[tot].right = -1;
                e[tot].v = x;
                e[tot].fa = y;
                e[tot].cnt = 1;
                sizee[tot] = 1;
                return;
            }
            insert(x,e[y].right);
        }
        update(y);
    }
    
    int query(int x)
    {
        int p = root,res = 0;
        while (p != -1)
        {
            if (x < e[p].v)
                p = e[p].left;
            else
            {
                res += getsize(e[p].left);
                if (x == e[p].v)
                    return res + 1;
                res += e[p].cnt;
                p = e[p].right;
            }
        }
        return res;
    }
    
    int query2(int x)
    {
        int p = root;
        while (p != -1)
        {
            if (e[p].left && x <= sizee[e[p].left])
            p = e[p].left;
            else
            {
                int temp = getsize(e[p].left) + e[p].cnt;
                if (x <= temp)
                return e[p].v;
                x -= temp;
                p = e[p].right;
            }
        }
        return p;
    }
    
    int findl(int x)
    {
        int p = root,maxx = 0x7fffffff,cur = x;
        while (p != -1)
        {
            if (e[p].v < x && x - e[p].v < maxx)
            {
                maxx = x - e[p].v;
                cur = e[p].v;
            }
            if (x <= e[p].v)
                p = e[p].left;
            else
                p = e[p].right;
        }
        return cur;
    }
    
    int findr(int x)
    {
        int p = root,maxx = 0x7fffffff,cur = x;
        while (p != -1)
        {
            if(e[p].v > x && e[p].v - x < maxx)
            {
                maxx = e[p].v - x;
                cur = e[p].v;
            }
            if (x >= e[p].v)
                p = e[p].right;
            else
                p = e[p].left;
        }
        return cur;
    }
    
    int main()
    {
        scanf("%d",&n);
        root = -1;
        for (int i = 1; i <= n; i++)
        {
            int opt,x;
            scanf("%d%d",&opt,&x);
            if (opt == 1)
            {
                if (root == -1)
                {
                    root = ++tot;
                    e[tot].left = e[tot].right = e[tot].fa = -1;
                    e[tot].cnt = 1;
                    e[tot].v = x;
                    sizee[tot] = 1;
                }
                else
                    insert(x,root);
                splay(tot);
                update(tot);
            }
            if (opt == 2)
                del(x);
            if (opt == 3)
                printf("%d
    ",query(x));
            if (opt == 4)
                printf("%d
    ",query2(x));
            if (opt == 5)
                printf("%d
    ",findl(x));
            if (opt == 6)
                printf("%d
    ",findr(x));
        }
    
        return 0;
    }
  • 相关阅读:
    PC-CSS-默认字体样式
    PC--CSS维护
    PC--CSS技巧
    PC--CSS优化
    PC--CSS命名
    PC--CSS常识
    Base64与MIME和UTF-7
    Base64算法与多版本加密技术
    Base64算法与MD5加密原理
    log4j的使用
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8261723.html
Copyright © 2020-2023  润新知