Treap tree template hdu-4585

Example: hdu 4585

Treap tree

It is a simple balanced binary search tree.
Each node of a binary search tree has a key, in addition to the tree for each node Treap artificially added a call priority weights. For the key, this is a binary search tree for the weights, this is a heap.

1, the uniqueness of the tree Treap

Treap tree important characteristic: for each different priority of the other node and the like, then the only, and no relationship insertion order form when the entire tree.

2, Treap tree balance

Depends on the shape of the tree node priority, then how to configure the priority of each node in order to avoid the form of a binary tree degenerate into a linked list? The simplest method when the priority of the random assignment of each node, the generated tree form Treap also random. Although this does not guarantee that every tree Treap generated when a certain balance, but the desired insert, delete, search complexity is O (logn) it is.

3, Treap tree data structure

struct Node{
    int size;  // 以这个点为根的子树的节点的数量
    int rank;  // 优先级
    int key;  // 键值
    Node *son[2];  //son[0]时左儿子,son[1]是右儿子
    bool operator < (const Node &a)const {return rank < a.rank;}
    int cmp(int x)const{
        if(x == key) return -1;
        return x < key? 0 : 1;
    }
    void update(){  //更新size
        size = 1;
        if(son[0] != NULL) size += son[0] -> size;
        if(son[1] != NULL) size += son[1] -> size;
    }
};

4, Treap tree insertion

Reads each new node, which is assigned a random priority, is inserted into the tree, the tree is dynamically adjusted during insertion configuration, it is still a Treap tree.
The new node inserted into the tree Treap two-step process
(1) with a simple method of inserting the node size key value into an appropriate subtree to.

(2) randomly assigned a priority level to the node, if the node priority in violation of the heap of nature, that it has higher priority than the parent, then let node to go up, instead of the parent node, and finally get a new tree Treap .

void insert(Node * &o, int x){  //插入
    if(o == NULL){
        o = new Node();
        o -> son[0] = o -> son[1] = NULL;
        o -> rank = rand();
        o -> key = x;
        o -> size = 1;
    }
    else{
        int d = o -> cmp(x);
        insert(o -> son[d], x);
        o -> update();
        if(o < o -> son[d])
            rotate(o, d^1);
    }
}

Rotation 5, the insertion process used in the maintenance of the heap

void rotate(Node * &o, int d){  // d = 0 左旋,d = 1右旋
    Node *k = o -> son[d^1];  //d^1 == 1 - d
    o -> son[d^1] = k -> son[d];
    k -> son[d] = o;
    o -> update();
    k -> update();
    o = k;
}

6, look for a large number of k-O (logn)

int kth(Node* o, int k){
    if(o == NULL || k <= 0 || k > o -> size)
        return -1;
    int s = o -> son[1] == NULL? 0: o -> son[1] -> size;
    if(k == s + 1) return o -> key;
    else if(k <= s) return kth(o -> son[1], k);
    else return kth(o -> son[0], k - s - 1);
}

7, a number of ranking queries O (logn)

int find(Node* o, int k){
    if(o == NULL) return -1;
    int d = o -> cmp(k);
    if(d == -1)
        return o -> son[1] == NULL? 1: o -> son[1] -> size + 1;
    else if(d == 1) return find(o -> son[d], k);
    else{
        int tmp = find(o -> son[d], k);
        if(tmp == -1) return -1;
        else
            return o -> son[1] == NULL? tmp + 1: tmp + 1 + o -> son[1] -> size;
    }
}

8, hdu 4585 AC Code

//#include <bits/stdc++.h>
#include <iostream>
#include <stack>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <list>
#include <map>
#include <algorithm>
#include <string.h>
#include <time.h>
using namespace std;
int id[5000000 + 5];
struct Node{
    int size;  // 以这个点为根的子树的节点的数量
    int rank;  // 优先级
    int key;  // 键值
    Node *son[2];  //son[0]时左儿子,son[1]是右儿子
    bool operator < (const Node &a)const {return rank < a.rank;}
    int cmp(int x)const{
        if(x == key) return -1;
        return x < key? 0 : 1;
    }
    void update(){  //更新size
        size = 1;
        if(son[0] != NULL) size += son[0] -> size;
        if(son[1] != NULL) size += son[1] -> size;
    }
};
 
void rotate(Node * &o, int d){  // d = 0 左旋,d = 1右旋
    Node *k = o -> son[d^1];  //d^1 == 1 - d
    o -> son[d^1] = k -> son[d];
    k -> son[d] = o;
    o -> update();
    k -> update();
    o = k;
}
 
void insert(Node * &o, int x){  //插入
    if(o == NULL){
        o = new Node();
        o -> son[0] = o -> son[1] = NULL;
        o -> rank = rand();
        o -> key = x;
        o -> size = 1;
    }
    else{
        int d = o -> cmp(x);
        insert(o -> son[d], x);
        o -> update();
        if(o < o -> son[d])
            rotate(o, d^1);
    }
}
 
int kth(Node* o, int k){
    if(o == NULL || k <= 0 || k > o -> size)
        return -1;
    int s = o -> son[1] == NULL? 0: o -> son[1] -> size;
    if(k == s + 1) return o -> key;
    else if(k <= s) return kth(o -> son[1], k);
    else return kth(o -> son[0], k - s - 1);
}
 
int find(Node* o, int k){
    if(o == NULL) return -1;
    int d = o -> cmp(k);
    if(d == -1)
        return o -> son[1] == NULL? 1: o -> son[1] -> size + 1;
    else if(d == 1) return find(o -> son[d], k);
    else{
        int tmp = find(o -> son[d], k);
        if(tmp == -1) return -1;
        else
            return o -> son[1] == NULL? tmp + 1: tmp + 1 + o -> son[1] -> size;
    }
}
 
int main(){
    int n;
    while(~scanf("%d", &n) && n){
        srand(time(NULL));
        int k, g;
        scanf("%d %d", &k, &g);
        Node *root = new Node();
        root -> son[0] = root -> son[1] = NULL;
        root -> rank = rand();
        root -> key = g;
        root -> size = 1;
        id[g] = k;
        printf("%d %d\n", k, 1);
        for(int i = 2; i <= n; i++){
            scanf("%d %d", &k, &g);
            id[g] = k;
            insert(root, g);
            int t = find(root, g);
            int ans1, ans2, ans;
            ans1 = kth(root, t - 1);
            ans2 = kth(root, t + 1);
            if(ans1 != -1 && ans2 != -1){
                ans = ans1 - g >= g - ans2? ans2: ans1;
            }
            else if(ans1 == -1) ans = ans2;
            else ans = ans1;
            printf("%d %d\n", k, id[ans]);
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/lihello/p/11520750.html