1. 程式人生 > >2018年東北農業大學春季校賽:L-wyh的天鵝(Treap)

2018年東北農業大學春季校賽:L-wyh的天鵝(Treap)

題意:插入元素,刪除元素,查詢第K大。

題解:Treap。

#include <bits/stdc++.h>
using namespace std;

#define Lc (o -> Ch[0])
#define Rc (o -> Ch[1])
#define val (o -> v)
#define pre (o -> p)
#define siz (o -> S)

const double EPS = 1e-8;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int maxn = 5e5 + 10;

struct Treap
{
    Treap* Ch[2];
    int p, v, S;
};

int root = 0, n, m, x;

void Update(Treap* &o)
{
    siz = 1;
    if(Lc != NULL) siz += Lc -> S;
    if(Rc != NULL) siz += Rc -> S;
}

void Rotate(Treap* &o, int d)
{
    Treap* P = o -> Ch[d ^ 1];
    o -> Ch[d ^ 1] = P -> Ch[d];
    P -> Ch[d] = o;
    Update(o); Update(P);
    o = P;
}

void Insert(Treap* &o, int x)
{
    if(o == NULL){
        o = new Treap();
        Lc = Rc = NULL;
        pre = rand();
        val = x;
    }
    else{
        int d = x < val;
        Insert(o -> Ch[d], x);
        if((pre) > o -> Ch[d] -> p) Rotate(o, d^1);
    }
    Update(o);
}

void Delete(Treap* &o, int x)
{
    if(val == x){
        if(Lc == NULL) o = Rc;
        else if(Rc == NULL) o = Lc;
        else{
            int T = (Lc -> p) < (Rc -> p);
            Rotate(o, T);
            Delete(o -> Ch[T], x);
        }
    }
    else Delete(o -> Ch[x < val], x);
    if(o != NULL) Update(o);
}

int Kth_Max(Treap* o, int k)
{
    if(o == NULL || k <= 0 || k > siz) return 0;
    int S = (Lc == NULL) ? 0 : (Lc -> S);
    if(k == S + 1) return val;
    else if(k <= S) return Kth_Max(Lc, k);
    else return Kth_Max(Rc, k - S - 1);
}

int main()
{
    int T;
    scanf("%d", &T);
    char s[10];
    while(T--){
        srand(time(NULL));
        scanf("%d%d", &n, &m);
        Treap* Root = NULL;
        for(int i = 1, x; i <= n; i++){
            scanf("%d", &x);
            Insert(Root, x);
        }
        while(m--){
            scanf("%s%d", s, &x);
            if(s[0] == 'q') printf("%d\n", Kth_Max(Root, x));
            else if(s[0] == 'i') Insert(Root, x);
            else Delete(Root, x);
        }
    }

    return 0;
}