我们知道,Treap可以完成节点的动态插入、删除、查询,其每个操作的时间复杂度是O(log n),因为其实现较红黑树更为简单,因此常常用于某些场合,以替换红黑树的实现。
Treap的每个节点维护了key, priority。
struct Node {
    int key;
    int priority;
    Node (int k, int p): key(k), priority(p) {}
}
key是作为BST的键值,用于支持快速的插入、删除和查询操作,而priority则是用于维护最小堆的性质。即从key层面上看,整个树是一个BST;从priority层面上看,则整个树是一个最小堆。
关于priority为何物?每当插入一个key值时,也会为它对应生成一个随机的priority。这个节点的插入操作分为两步:
Treap除去支持insert, find, remove等,还支持快速地查找到最小的priority。于是我们又可以通过STL中的map,set等模拟之。
insert(string key, int value),插入一个pair,时间复杂度要求为 O(log n)lookup(string key), 查询,时间复杂度要求为O(log n)remove(string key),删除一个节点,时间复杂度要求为O(log n)max(),获得当前所有节点中最大的value,时间复杂度要求为O(1)显然,insert, find, remove 等方法就可以用BST搞定,比如直接使用STL的map(时间复杂度为O(log n),而STL的unordered_map时间复杂度为O(1)),但是max如何搞定呢?STL的map不支持对所有的value进行维护,比如取得最大值。
那么可以使用两个map+set来搞定,思路如下:
unordered_map<string, int> mp,用于O(1)的时间来对key进行查找map<int, unordered_set<string> > mp_reverse,mp_reverse用O(log n)的时间可以取得当前value的最大值,最小值,并且针对每个value,都可以查询到对应的所有的key值。代码如下:
#include <iostream>
#include <map>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <cstdio>
#include <cstdlib>
using namespace std;
// using map and set to simulate a Treap
class Solution {
public:
    unordered_map<string, int> mp;
    map<int, unordered_set<string> > mp_reverse;
    void test() {
        insert("a", 3);
        insert("b", 6);
        cout << "a: " << lookup("a") << endl;
        cout << "max: " << max() << endl;
        insert("a", 7);
        cout << "a: " << lookup("a") << endl;
        cout << "max: " << max() << endl;
        remove("a");
        cout << "max: " << max() << endl;
    }
    // insert a pair(key, value), if the key exists, then override the previous entry
    // time complexity: O(log n)
    void insert(string key, int value) {
        // first check whether key exists
        int pre_value = lookup(key);
        if (pre_value != -1) remove(key);
        // first step of inserting
        mp.insert(make_pair(key, value)); 
        // second step of inserting
        map<int, unordered_set<string> >::iterator iter = mp_reverse.find(value);
        if (iter == mp_reverse.end()) {
            unordered_set<string> s; 
            s.insert(key);
            mp_reverse.insert(make_pair(value, s));
        } else {
            iter->second.insert(key);
        }
    }
    // remove a pair(key, value)
    // time complexity: O(log n)
    void remove(string key) {
        int value;
        if ((value=lookup(key)) == -1) return;
        mp.erase(key);  // first step of erasing
        map<int, unordered_set<string> >::iterator iter = mp_reverse.find(value);
        if (iter != mp_reverse.end()) iter->second.erase(key); // second step of erasing
        if (iter->second.empty()) mp_reverse.erase(value); // third step of eraing
    }
    // lookup an entry with key
    // time complexity: O(log n)
    int lookup(string key) {
        unordered_map<string, int>::iterator iter = mp.find(key);
        if (iter == mp.end()) return -1; // cannot find the key
        return iter->second;
    }
    // return the maximun value
    // time complexity: O(1)
    string max() {
        map<int, unordered_set<string> >::iterator iter = mp_reverse.end();
        iter--;
        if (!iter->second.empty()) 
            return *(iter->second.begin());
    }
};
int main() {
    Solution solution;
    solution.test();
}
// output
a: 3
max: b
a: 7
max: a
max: b原文:http://blog.csdn.net/nisxiya/article/details/45130445