Treap模板

平衡树总是有用的,set由于过度封装没有办法实现找比x小的元素有多少个,这就显得很不方便了,所以封装了个Treap,万一以后用的着呢- -01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <algorithm>
using namespace std;
 
#define maxn 420000
const int inf = ~0U >> 1;
struct Node
{
    int val, key, size; // value stored,priority key,size of total,number of current value
    Node *ch[2];
    Node(){
        val = size = 0;
        key = inf;
    }
    void upd(){
        size = ch[0]->size + ch[1]->size + 1;
    }
};
 
Node mem[maxn], *C = mem;
 
Node *make(int v,Node *p){
    C->ch[0] = C->ch[1] = p;
    C->val = v; C->key = rand() - 1;
    C->size = 1;
    return C++;
}
 
Node *make_null(){
    C->ch[0] = C->ch[1] = 0;
    C->val = 0; C->key = inf;
    C->size = 0;
    return C++;
}
 
struct Treap
{
private:
    Node *root, *null;
    void rot(Node *&u, int d){
        Node *v = u->ch[d];
        u->ch[d] = v->ch[!d];
        v->ch[!d] = u;
        u->upd(); v->upd();
        u = v;
    }
    void insert(Node *&u, int k){
        if (u == null) u = make(k, null);
        else if (u->val == k) return;
        else{
            int d = k > u->val;
            Node *&v = u->ch[d];
            insert(v, k);
            if (v->key < u->key) rot(u, d);
        }
        u->upd();
    }
    void erase(Node *&u, int k){
        if (u == null) return;
        if (u->val == k){
            int d = u->ch[1]->key < u->ch[0]->key;
            if (u->ch[d] == null) {
                u = null; return;
            }
            rot(u, d);
            erase(u->ch[!d], k);
        }
        else erase(u->ch[k>u->val], k);
        u->upd();
    }
    // left side has size of k
    Node *select(Node *u, int k){
        int r = u->ch[0]->size;
        if (k == r)
            return u;
        if (k < r) return select(u->ch[0], k);
        return select(u->ch[1], k - r - 1);
    }
    // return the number of elements smaller than x
    int rank(Node *u, int x){
        if (u == null) return 0;
        int r = u->ch[0]->size;
        if (x == u->val) return r;
        else if (x < u->val) return  rank(u->ch[0], x);
        else return r + 1 + rank(u->ch[1], x);
    }
    bool find(Node *u, int x){
        if (u == null) return false;
        if (x == u->val) return true;
        else return find(u->ch[x>u->val], x);
    }
public:
    Treap(){
        null = make_null();
        root = null;
    }
    void init(){
        null = make_null();
        root = null;
    }
    void insert(int x){
        insert(root, x);
    }
    void erase(int x){
        erase(root, x);
    }
    int select(int k){
        if (k > root->size) return -inf;
        else return select(root, k - 1)->val;
    }
    // return the element that is smaller than x
    int rank(int x){
        return rank(root, x);
    }
    // return whether x exist
    bool find(int x){
        return find(root, x);
    }
}treap;
 
int main()
{
    int m; scanf("%d\n", &m);
    char cmd;
    int x;
    while (m--){
        scanf("%c %d\n", &cmd, &x);
        if (cmd == 'I') treap.insert(x);
        else if (cmd == 'D') treap.erase(x);
        else if (cmd == 'K') {
            int ans = treap.select(x);
            if (ans == -inf) printf("invalid\n");
            else printf("%d\n", ans);
        }
        else{
            printf("%d\n", treap.rank(x));
        }
    }
    return 0;
}

 

posted @   chanme  阅读(263)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示