zoukankan      html  css  js  c++  java
  • [bzoj 3224]手写treap

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3224

    bzoj不能用time(0),看到这个博客才知道,我也RE了好几发……

    #include<bits/stdc++.h>
    using namespace std;
    
    struct Node
    {
        int val,pri,sz,cnt;
        Node* ch[2];
        int cmp(int x) const
        {
            if (x==val) return -1;
            return x<val?0:1;
        }
        void push_up()
        {
            sz=cnt+ch[0]->sz+ch[1]->sz;
        }
    }*tree,*null;
    
    void rotate(Node* &node,int d)
    {
        Node *k=node->ch[d];
        node->ch[d]=k->ch[d^1];
        k->ch[d^1]=node;
        node=k;
    }
    
    void insert(Node* &node,int x)
    {
        if (node==null)
        {
            node=new Node();
            node->ch[0]=null;
            node->ch[1]=null;
            node->val=x;
            node->cnt=1;
            node->pri=rand();
            node->sz=1;
        }
        else
        {
            int d=node->cmp(x);
            if (d==-1)
            {
                node->cnt++;
                node->sz++;
            }
            else
            {
                insert(node->ch[d],x);
                if (node->pri < node->ch[d]->pri)
                {
                    rotate(node,d);
                    node->ch[d^1]->push_up();
                }
                node->push_up();
            }
        }
    }
    
    void remove(Node* &node,int x)
    {
        if (node==null) return;
        int d=node->cmp(x);
        if (d==-1)
        {
            if (node->cnt>1)
            {
                node->cnt--;
                node->sz--;
            }
            else
            {
                if (node->ch[1]==null)
                {
                    Node *tmp=node;
                    node=node->ch[0];
                    delete tmp;
                }
                else if (node->ch[0]==null)
                {
                    Node *tmp=node;
                    node=node->ch[1];
                    delete tmp;
                }
                else
                {
                    int dd=(node->ch[0]->pri)<(node->ch[1]->pri)?1:0;
                    rotate(node,dd);
                    remove(node->ch[dd^1],x);
                }
            }
        }
        else remove(node->ch[d],x);
        node->push_up();
    }
    
    int rk(const Node* node,int x)
    {
        if (node==null) return 0;
        if (node->val<x) return node->cnt+node->ch[0]->sz+rk(node->ch[1],x);
        else return rk(node->ch[0],x);
    }
    
    int kth(const Node* node,int k)
    {
        if (node->ch[0]==null)
        {
            if (node->cnt>=k) return node->val;
            else return kth(node->ch[1],k-node->cnt);
        }
        else
        {
            if (node->ch[0]->sz>=k) return kth(node->ch[0],k);
            if (node->ch[0]->sz+node->cnt>=k) return node->val;
            return kth(node->ch[1],k-node->ch[0]->sz-node->cnt);
        }
    }
    
    int pre(Node* node,int x)
    {
        Node *t=node;
        int res=-0x3f3f3f3f;
        while (t!=null)
        {
            if (t->val>=x) t=t->ch[0];
            else res=t->val,t=t->ch[1];
        }
        return res;
    }
    
    int suc(Node* node,int x)
    {
        Node *t=node;
        int res=0x3f3f3f3f;
        while (t!=null)
        {
            if (t->val<=x) t=t->ch[1];
            else res=t->val,t=t->ch[0];
        }
        return res;
    }
    
    int main()
    {
        //srand((unsigned)time(NULL));
        null=new Node();
        null->cnt=0;
        null->sz=0;
        null->pri=-1;
        null->ch[0]=null;
        null->ch[1]=null;
        tree=null;
        int n;
        scanf("%d",&n);
        while (n--)
        {
            int op,x;
            scanf("%d%d",&op,&x);
            switch(op)
            {
                case 1: insert(tree,x); break;
                case 2: remove(tree,x); break;
                case 3: printf("%d
    ",rk(tree,x)+1); break;
                case 4: printf("%d
    ",kth(tree,x)); break;
                case 5: printf("%d
    ",pre(tree,x)); break;
                case 6: printf("%d
    ",suc(tree,x)); break;
            }
        }
        return 0;
    }
  • 相关阅读:
    Ubuntu 12.04 gedit编辑器 中文乱码
    ubuntu设置vim语法高亮显示和自动缩进
    Linux学习小结(转)
    指向常量的指针和常量指针
    Android之EditText
    android之TextView
    Android存储机制之Preference
    android实现可拖动按钮
    用turtle画图
    torchvision里densenet代码分析
  • 原文地址:https://www.cnblogs.com/acmsong/p/7601501.html
Copyright © 2011-2022 走看看