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;
    }
  • 相关阅读:
    js对象的直接赋值、浅拷贝与深拷贝
    如何使ElementUi中的el-dropdown传入多参数
    机器学习之垃圾邮件分类2
    机器学习之手写数字识别-小数据集
    机器学习之深度学习-卷积
    机器学习之朴素贝叶斯-垃圾邮件分类
    机器学习之分类与监督学习,朴素贝叶斯分类算法
    机器学习之主成分分析(PCA&特征选择)
    机器学习之逻辑回归实践
    机器学习之特征选择
  • 原文地址:https://www.cnblogs.com/acmsong/p/7601501.html
Copyright © 2011-2022 走看看