题解 P2343 【宝石管理系统】

· · 题解

题目大意:开始给出m个宝石,它们有各自的价值,然后会有好多询,或后者添加宝石操作,添加宝石就是把新宝石加入宝石堆里,询问的话是找价值第n大的宝石。

我一看这题就想到了一个叫做平衡树的东西,平衡树是二叉搜索树和堆合并构成的新数据结构,所以它的名字取了Tree和Heap各一半,叫做Treap,非常好用,而且这道题并不需要打整颗平衡树,只需要插入宝石到数中,在rank就行了

这个就是一个平衡树。不会的话就顺便去这里:(https://blog.csdn.net/qq_21120027/article/details/51713248) 学一个新的数据结构吧。。。

/*
ID:wang1441
LANG: C++
TASK:
*/
#include<bits/stdc++.h>
#define ll long long

using namespace std;

inline int read()
{
    int x=0;
    char ch=getchar();
    char c=ch;
    while(ch>'9'||ch<'0')c=ch,ch=getchar();
    while(ch<='9'&&ch>= '0')x=x*10+ch-'0',ch=getchar();
    if(c=='-')x=x*-1;
    return x;
}
//const int maxn=,maxm=;
struct node{
    node *wudi[2];
    int r,v,s;
    int cmp(int x)const
    {
        return x>v?0:1;
    }
    void maintain(){
        s=wudi[0]->s+wudi[1]->s+1;
    }
}*null,*root;

int a[100010];
int n,m;
int q,c;

void wwwwww(node * &o,int d)
{
    node * k=o->wudi[d^1];
    o->wudi[d^1]=k->wudi[d];
    o->maintain();
    k->maintain();
    k->wudi[d]=o;
    o=k;
}

void eeeeee(node * &o,int x)
{
    if(o==null){
        o=new node();
        o->wudi[0]=o->wudi[1]=null;
        o->v=x;
        o->r=rand();
        o->maintain();
    }
    else{
        int d=o->cmp(x);
        eeeeee(o->wudi[d],x);
        if(o->wudi[d]->r>o->r)
            wwwwww(o,d^1);
        o->maintain();
    }
}

void tttttttttt()
{
    null=new node();
    null->s=0;
    root=null; 
}

void rrrrrrrrrrr(node * o,int x)
{
    if(o==null)
        return ;
    int d=o->wudi[0]->s;
    if(x==d+1){
        printf("%d\n",o->v);
        return ;
    }
    if(x<d+1)
        rrrrrrrrrrr(o->wudi[0],x);
    else
        rrrrrrrrrrr(o->wudi[1],x-d-1);
}

int main()
{
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    tttttttttt();
    m=read();
    q=read();
    srand(time(NULL));
    for(register int i=1;i<=m;i++){
        a[i]=read();
        eeeeee(root,a[i]);
    }
    for(register int i=1;i<=q;i++){
        c=read();
        n=read();
        if(c==1){
            rrrrrrrrrrr(root,n);
        }
        if(c==2){
            eeeeee(root,n);
        }
    }
}