[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\n",rk(tree,x)+1); break;
            case 4: printf("%d\n",kth(tree,x)); break;
            case 5: printf("%d\n",pre(tree,x)); break;
            case 6: printf("%d\n",suc(tree,x)); break;
        }
    }
    return 0;
}

 

posted @ 2017-09-27 14:10  ACMsong  阅读(169)  评论(0编辑  收藏  举报