这道题就是裸裸的TREAP,然后TREAP的裸题好像已经写过了,于是决定试试写FANHQ TREAP,一开始我插入没写旋转,后来仔细研究了FANHQ的博客,才知道后来他加了旋转(说好的没有旋转呢),然后我去加了旋转果断快了50ms

关于FANHQ TREAP,当然是去看FANHQ在WC上讲课的材料和FANHQ的博客咯: 范浩强_wc2012谈谈各种数据结构.pdf   在线预览 挖掘Treap的潜力- fanhq666的日志- 网易博客

然后贴上我的程序,貌似不算快

//BZOJ 3224.cpp fanhq_treap
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<cmath>
#include<queue>
#include<stack>

//#define LOCAL
//#define VISUAL_STUDIO
#define READ_FREAD
//#define READ_FILE

#ifdef VISUAL_STUDIO
#pragma warning(disable:4996)
#endif

#ifdef LOCAL
#define LOCAL_TIME
//#define DEBUG_DETAIL
//#define DEBUG_ID
//#define DEBUG_SIZE
//#define LOCAL_DEBUG
//#define STD_DEBUG
#endif

#ifdef LOCAL_TIME
#include<ctime>
#endif

#ifdef READ_FREAD
const int MAXS = 10 * 1024 * 1024;

char fread_string[MAXS];
char *fread_point = fread_string;

inline int get_int()
{
    int ret = 0;
    int sign = 1;
    while ((*fread_point < '0') || (*fread_point > '9'))
    {
        sign = 1;
        if (*fread_point == '-')
        {
            sign = -1;
        }
        fread_point++;
    }
    while ((*fread_point >= '0') && (*fread_point <= '9'))
    {
        ret = ret * 10 + *(fread_point++) - '0';
    }
    return sign * ret;
}
#endif

inline void read(int &input_num)
{
#ifdef READ_FREAD
    input_num = get_int();
#else
    scanf("%d", &input_num);
#endif
}

typedef long long ll;

/*---rank---*/
const int rank_base = 1753;

inline int get_rank()
{
    return (rand() << 11) + rand();
}
/*---rank---*/

struct treap_node
{
    int val, rank, size;
    treap_node *l_child, *r_child, *parent;
    inline treap_node *init(const int val_ = 0, treap_node *l_child_ = NULL, treap_node *r_child_ = NULL, treap_node *parent_ = NULL)
    {
        val = val_;
        size = 1;
        l_child = l_child_;
        r_child = r_child_;
        parent = parent_;
        return this;
    }
    inline treap_node()
    {
        init();
    }
};

#ifndef NULL
#define NULL 0
#endif

/*---recover memory---*/
const int MAXN = 100000;

treap_node node_memory[MAXN];
treap_node *memory_stack[MAXN];
int treap_top = MAXN;

inline void init_memory()
{
    for (int i = 0; i < MAXN; i++)
    {
        memory_stack[i] = node_memory + i;
        node_memory[i].rank = get_rank();
    }
}

inline treap_node *new_node(const int val = 0, treap_node *l_child = NULL, treap_node *r_child = NULL, treap_node *parent = NULL)
{
    return memory_stack[--treap_top]->init(val, l_child, r_child, parent);
}

inline void delete_node(treap_node *del_node)
{
    memory_stack[treap_top++] = del_node;
    del_node->init();
}
/*---recover memory---*/

treap_node *head;

/*---treap---*/
inline void attach_as_l_child(treap_node *parent, treap_node *child)
{
    parent->l_child = child;
    if (child != NULL)
    {
        child->parent = parent;
    }
}

inline void attach_as_r_child(treap_node *parent, treap_node *child)
{
    parent->r_child = child;
    if (child != NULL)
    {
        child->parent = parent;
    }
}

inline int treap_size(treap_node *size_node)
{
    if (size_node == NULL)
    {
        return 0;
    }
    return size_node->size;
}

inline void treap_update_size(treap_node *update_node)
{
    update_node->size = treap_size(update_node->l_child) + treap_size(update_node->r_child) + 1;
}

inline void treap_update(treap_node *update_node)
{
    treap_update_size(update_node);
}

treap_node *treap_merge(treap_node *merge_left, treap_node *merge_right)
{
    if ((merge_left == NULL) && (merge_right == NULL))
    {
        return NULL;
    }
    if (merge_left == NULL)
    {
        return merge_right;
    }
    if (merge_right == NULL)
    {
        return merge_left;
    }
    if (merge_left->rank < merge_right->rank)
    {
        attach_as_r_child(merge_left, treap_merge(merge_left->r_child, merge_right));
        treap_update(merge_left);
        return merge_left;
    }
    else
    {
        attach_as_l_child(merge_right, treap_merge(merge_left, merge_right->l_child));
        treap_update(merge_right);
        return merge_right;
    }
    return NULL;
}

inline treap_node *treap_search_val(const int val, const int add_size = 0, bool get_same = true)
{
    treap_node *last_visit = head;
    treap_node *found = NULL;
    for (treap_node *tmp = head; tmp != NULL;)
    {
        last_visit = tmp;
        if (tmp->val == val)
        {
            found = tmp;
            tmp = tmp->l_child;
        }
        else if (tmp->val < val)
        {
            tmp = tmp->r_child;
        }
        else
        {
            tmp = tmp->l_child;
        }
    }
    for (treap_node *tmp = ((found != NULL) && get_same ? found->parent : last_visit); tmp != NULL; tmp = tmp->parent)
    {
        tmp->size += add_size;
    }
    return ((found != NULL) && get_same ? found : last_visit);
}

inline void zig(treap_node *axis)
{

    treap_node *left_child = axis->l_child;
    treap_node *parent = axis->parent;
    attach_as_l_child(axis, left_child->r_child);
    attach_as_r_child(left_child, axis);
    left_child->parent = parent;
    if (parent == NULL)
    {
        head = left_child;
    }
    else if (parent->l_child == axis)
    {
        parent->l_child = left_child;
    }
    else
    {
        parent->r_child = left_child;
    }
    treap_update(axis);
    treap_update(left_child);
}

inline void zag(treap_node *axis)
{
    treap_node *right_child = axis->r_child;
    treap_node *parent = axis->parent;
    attach_as_r_child(axis, right_child->l_child);
    attach_as_l_child(right_child, axis);
    right_child->parent = parent;
    if (parent == NULL)
    {
        head = right_child;
    }
    else if (parent->l_child == axis)
    {
        parent->l_child = right_child;
    }
    else
    {
        parent->r_child = right_child;
    }
    treap_update(axis);
    treap_update(right_child);
}
inline void treap_route(treap_node *route_node)
{
    while ((route_node->parent != NULL) && (route_node->rank < route_node->parent->rank))
    {
        if (route_node->parent->l_child == route_node)
        {
            zig(route_node->parent);
        }
        else
        {
            zag(route_node->parent);
        }
    }
}

inline void treap_insert(const int val)
{
    treap_node *tmp = new_node(val);
    if (head == NULL)
    {
        head = tmp;
    }
    else
    {
        treap_node *insert_pt = treap_search_val(val, 1, false);
        if (insert_pt->val < val)
        {
            attach_as_r_child(insert_pt, tmp);
        }
        else
        {
            attach_as_l_child(insert_pt, tmp);
        }
        treap_route(insert_pt);
    }
}

inline void treap_delete(const int val)
{
    treap_node *del_node = treap_search_val(val, -1);
    treap_node *tmp = treap_merge(del_node->l_child, del_node->r_child);
    if (del_node->parent == NULL)
    {
        head = tmp;
        tmp->parent = NULL;
    }
    else if (del_node->parent->l_child == del_node)
    {
        attach_as_l_child(del_node->parent, tmp);
    }
    else
    {
        attach_as_r_child(del_node->parent, tmp);
    }
    delete_node(del_node);
}

inline int treap_rank(const int val)
{
    int ret = -1;
    int rank = 0;
    for (treap_node *tmp = head; tmp != NULL;)
    {
        if (tmp->val == val)
        {
            ret = rank + treap_size(tmp->l_child) + 1;
            tmp = tmp->l_child;
        }
        else if (tmp->val < val)
        {
            rank += treap_size(tmp->l_child) + 1;
            tmp = tmp->r_child;
        }
        else
        {
            tmp = tmp->l_child;
        }
    }
    return ret;
}

inline int treap_num(const int rank)
{
    int size = 0;
    for (treap_node *tmp = head; tmp != NULL;)
    {
        if (size + treap_size(tmp->l_child) + 1 == rank)
        {
            return tmp->val;
        }
        if (size + treap_size(tmp->l_child) + 1 < rank)
        {
            size += treap_size(tmp->l_child) + 1;
            tmp = tmp->r_child;
        }
        else
        {
            tmp = tmp->l_child;
        }
    }
    return -1;
}

inline int treap_prev(const int val)
{
    int max = -1;
    for (treap_node *tmp = head; tmp != NULL;)
    {
        if (tmp->val < val)
        {
            if (tmp->val > max)
            {
                max = tmp->val;
            }
            tmp = tmp->r_child;
        }
        else
        {
            tmp = tmp->l_child;
        }
    }
    return max;
}

inline int treap_next(const int val)
{
    int min = -1;
    for (treap_node *tmp = head; tmp != NULL;)
    {
        if (tmp->val > val)
        {
            if ((min == -1) || (tmp->val < min))
            {
                min = tmp->val;
            }
            tmp = tmp->l_child;
        }
        else
        {
            tmp = tmp->r_child;
        }
    }
    return min;
}

#ifdef LOCAL_DEBUG
int checker_prev = -1;
inline void treap_checker(treap_node *root = head)
{
    if (root == NULL)
    {
        return;
    }
    int size = 0;
    if (root->l_child != NULL)
    {
        if (root->l_child->parent != root)
        {
            printf("ERROR ");
        }
        treap_checker(root->l_child);
        size += root->l_child->size;
    }
    printf("%d ", root->val);
    if (root->val < checker_prev)
    {
        printf("ERROR_ORDER ");
    }
    checker_prev = root->val;
    if (root->r_child != NULL)
    {
        if (root->r_child->parent != root)
        {
            printf("ERROR ");
        }
        treap_checker(root->r_child);
        size += root->r_child->size;
    }
    if (size + 1 != root->size)
    {
        printf("E %d ERROR_SIZE ", root->val);
    }
}
#endif
/*---treap---*/

const int OP_INS = 1;
const int OP_DEL = 2;
const int OP_QRK = 3;
const int OP_QNM = 4;
const int OP_PRE = 5;
const int OP_NET = 6;

int n;
int operator_num, x;

int main()
{
#ifdef LOCAL_TIME
    ll start_time_ = clock();
#endif
#ifdef READ_FILE
    freopen("3224.in", "r", stdin);
#ifndef STD_DEBUG
#ifdef LOCAL_DEBUG
    freopen("3224_debug.out", "w", stdout);
#else
    freopen("3224.out", "w", stdout);
#endif
#endif
#endif
#ifdef READ_FREAD
    fread(fread_string, 1, MAXS, stdin);
#endif
    srand(rank_base);
    init_memory();
    read(n);
#ifdef DEBUG_SIZE
    int size = 0;
#endif
    for (int i = 0; i < n; i++)
    {
        read(operator_num);
        read(x);
#ifdef LOCAL_DEBUG
        printf("INPUT: %d %d %dn", i, operator_num, x);
        if (i == 6)
        {
            printf("DEBUG:6n");
        }
#endif
#ifdef DEBUG_DETAIL
        if (i == 3506)
        {
            printf("DEBUG:3506n");
        }
#endif
#ifdef DEBUG_ID
        printf("%d ", i);
#endif
        if (operator_num == OP_INS)
        {
#ifdef DEBUG_SIZE
            size++;
#endif
            treap_insert(x);
        }
        else if (operator_num == OP_DEL)
        {
#ifdef DEBUG_SIZE
            size--;
#endif
            treap_delete(x);
        }
        else if (operator_num == OP_QRK)
        {
            printf("%dn", treap_rank(x));
        }
        else if (operator_num == OP_QNM)
        {
            printf("%dn", treap_num(x));
        }
        else if (operator_num == OP_PRE)
        {
            printf("%dn", treap_prev(x));
        }
        else if (operator_num == OP_NET)
        {
            printf("%dn", treap_next(x));
        }
#ifdef DEBUG_SIZE
        if (size != head->size)
        {
            printf("ERROR!!n");
        }
#endif
#ifdef LOCAL_DEBUG
        checker_prev = -1;
        printf("DEBUG: ");
        treap_checker();
        printf("n");
#endif
    }
#ifdef LOCAL_TIME
    printf("run time: %lld ms", clock() - start_time_);
#endif
#ifdef READ_FILE
    fclose(stdin);
#ifndef STD_DEBUG
    fclose(stdout);
#endif
#endif
    return 0;
}