Fork me on GitHub

UESTC 395 Dynamic Query System --Treap

题意:让你维护一个集合,有8种操作:

1.  I x  插入一个数

2.  R x 删除x

3.  S 输出总的数个数(集合大小)

4.  L x  查询小于x的数的个数

5.  W k  查询集合中数从小到大排列的第k个数

6.  C x  查询x的个数

7.  MI  查询集合中最小的数

8.  MA 查询集合中最大的数

 

一道平衡树模拟的裸题,直接套版然后改下细节就行了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

struct node
{
    node *ch[2];
    int v,r,sz,cnt;
    void UP(){ sz = ch[0]->sz + ch[1]->sz + cnt; }
    int cmp(int x)const
    {
        if(x == v) return -1;
        return x > v;
    }
}*null,*root;

void create(node *&o,int v=0)
{
    o = new node();
    o->sz = o->cnt = 1;
    o->v = v;
    o->r = rand();
    o->ch[0] = o->ch[1] = null;
}

void rotate(node *&o,int d)
{
    node *p = o->ch[d];
    o->ch[d] = p->ch[d^1];
    p->ch[d^1] = o;
    o->UP(),p->UP();
    o = p;
}

int countx(node *o,int v)
{
    while(o != null)
    {
        int d = o->cmp(v);
        if(d == -1)
            return o->cnt;
        o = o->ch[d];
    }
    return 0;
}

void insert(node *&o,int v)
{
    if(o == null)
    {
        create(o,v);
        return;
    }
    int d = o->cmp(v);
    if(d == -1)
    {
        o->cnt++;
        o->UP();
        return;
    }
    insert(o->ch[d],v);
    if(o->r > o->ch[d]->r)
        rotate(o,d);
    if(o != null)
        o->UP();
}

void del(node *&o,int v)
{
    if(o == null) return;
    int d = o->cmp(v);
    if(d == -1)
    {
        if(o->cnt > 1)
            o->cnt--;
        else
        {
            if(o->ch[0] == null) o = o->ch[1];
            else if(o->ch[1] == null) o = o->ch[0];
            else
            {
                int d2 = o->ch[1]->r < o->ch[0]->r;
                if(o->ch[d2] == null)
                {
                    delete o;
                    o = null;
                    return;
                }
                rotate(o,d2);
                del(o->ch[d2^1],v);
            }
        }
    }
    else del(o->ch[d],v);
    if(o != null)
        o->UP();
}

int Kth(node *o,int k)
{
    if(o == null || k == 0 || k > o->sz) return -1;
    int left = o->ch[0]->sz;
    if(k > left && k <= left + o->cnt)
        return o->v;
    if(k > left + o->cnt)
        return Kth(o->ch[1],k-left-o->cnt);
    return Kth(o->ch[0],k);
}

int Count(node *o,int v)
{
    if(o == null) return 0;
    int left = o->ch[0]->sz;
    if(o->v == v) return left;
    else if(v < o->v)
        return Count(o->ch[0],v);
    return Count(o->ch[1],v)+left+o->cnt;
}

void init()
{
    create(null);
    null->sz = 0;
    root = null;
}

int main()
{
    int t,n,i,x;
    char ss[3];
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d",&n);
        while(n--)
        {
            scanf("%s",ss);
            if(ss[0] == 'M')
            {
                if(ss[1] == 'I')
                    printf("%d\n",Kth(root,1));
                else
                    printf("%d\n",Kth(root,root->sz));
            }
            else if(ss[0] == 'I')
            {
                scanf("%d",&x);
                insert(root,x);
            }
            else if(ss[0] == 'S')
            {
                printf("%d\n",root->sz);
            }
            else if(ss[0] == 'R')
            {
                scanf("%d",&x);
                del(root,x);
            }
            else if(ss[0] == 'L')
            {
                scanf("%d",&x);
                printf("%d\n",Count(root,x));
            }
            else if(ss[0] == 'W')
            {
                scanf("%d",&x);
                printf("%d\n",Kth(root,x));
            }
            else if(ss[0] == 'C')
            {
                scanf("%d",&x);
                printf("%d\n",countx(root,x));
            }
        }
    }
    return 0;
}
View Code

 

posted @ 2014-12-18 09:44  whatbeg  阅读(185)  评论(0编辑  收藏  举报