平衡树三件套的第三题目测要树套,我太弱了所以不会,只好接着用FANHQ_TREAP水第二题了。听说这题目只有一个操作,于是很高端地用了FANHQ_TREAP。但是莫名其妙写得好慢,比RANK1慢了1S多,一定是还有什么神奇的算法,求教。。

关于FANHQ_TREAP的问题详见我的上一篇日志[TYVJ1728]普通平衡树(FANHQ_TREAP)FANHQ_TREAP好像能实现SPLAY几乎全部的操作,而且支持持久化,常数又小,听起来就很高端。。

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

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

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

#ifdef LOCAL
#define LOCAL_TIME
//#define LOCAL_DEBUG
//#define STD_DEBUG
#endif

#ifdef LOCAL_TIME
#include<ctime>
#endif

#ifndef NULL
#define NULL 0
#endif

typedef long long ll;

#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;
    char fread_point = getchar();
    while ((fread_point < '0') || (fread_point >  '9'))
    {
        fread_point = getchar();
    }
    while ((fread_point >= '0') && (fread_point <= '9'))
    {
        ret = ret * 10 + fread_point - '0';
        fread_point = getchar();
    }
    return ret;
}
#endif

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

/*---rank---*/
const int rand_base = 79;

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

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

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

treap_node node_memory[MAXN];
treap_node *memory_stack[MAXN];
int stack_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 = -1, treap_node *l_child = NULL, treap_node *r_child = NULL, treap_node *parent = NULL)
{
    return memory_stack[--stack_top]->init(val, l_child, r_child, parent);
}

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

treap_node *head = NULL;

/*---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 void treap_swap(treap_node *swap_node)
{
    if (swap_node == NULL)
    {
        return;
    }
    std::swap(swap_node->l_child, swap_node->r_child);
    swap_node->down_swap = !swap_node->down_swap;
}

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

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

inline void treap_down_swap(treap_node *down_node)
{
    if (down_node == NULL)
    {
        return;
    }
    if (down_node->down_swap)
    {
        treap_swap(down_node->l_child);
        treap_swap(down_node->r_child);
        down_node->down_swap = false;
    }
}

inline void treap_down(treap_node *down_node)
{
    treap_down_swap(down_node);
}

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

inline void zig(treap_node *axis)
{
    treap_node *left_child = axis->l_child;
    treap_node *parent = axis->parent;
    treap_down(axis);
    treap_down(left_child);
    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;
    treap_down(axis);
    treap_down(right_child);
    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_insert_size(treap_node *v)
{
    for (; v != NULL; v = v->parent)
    {
        v->size++;
    }
}

void treap_cut(treap_node *root, treap_node *&treap_left, treap_node *&treap_right, const int cut_left)
{
    if (cut_left == 0)
    {
        treap_left = NULL;
        treap_right = root;
    }
    else if (cut_left == treap_size(root))
    {
        treap_left = root;
        treap_right = NULL;
    }
    if (root == NULL)
    {
        treap_left = NULL;
        treap_right = NULL;
        return;
    }
    else
    {
        treap_down(root);
        if (treap_size(root->l_child) + 1 <= cut_left)
        {
            treap_left = root;
            treap_cut(root->r_child, treap_left->r_child, treap_right, cut_left - treap_size(root->l_child) - 1);
            if (treap_left->r_child != NULL)
            {
                treap_left->r_child->parent = treap_left;
            }
            treap_update(treap_left);
        }
        else
        {
            treap_right = root;
            treap_cut(root->l_child, treap_left, treap_right->l_child, cut_left);
            if (treap_right->l_child != NULL)
            {
                treap_right->l_child->parent = treap_right;
            }
            treap_update(treap_right);
        }
    }
}

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

inline void treap_route(treap_node *v)
{
    while ((v->parent != NULL) && (v->rank < v->parent->rank))
    {
        if (v->parent->l_child == v)
        {
            zig(v->parent);
        }
        else
        {
            zag(v->parent);
        }
    }
}

inline void treap_insert(const int n)
{
    treap_node *v = NULL;
    for (int i = 1; i <= n; i++)
    {
        treap_node *insert_node = new_node(i);
        if (v == NULL)
        {
            head = insert_node;
        }
        else
        {
            attach_as_r_child(v, insert_node);
            treap_insert_size(v);
            treap_route(insert_node);
        }
        v = insert_node;
    }
}

inline void treap_reverse(const int l, const int r)
{
    treap_node *treap_l = NULL, *treap_r = NULL, *treap_reverse = NULL;
    treap_cut(head, treap_l, treap_r, l - 1);
    treap_cut(treap_r, treap_reverse, treap_r, r - l + 1);
    treap_swap(treap_reverse);
    treap_l = treap_merge(treap_l, treap_reverse);
    head = treap_merge(treap_l, treap_r);
    head->parent = NULL;
}

void treap_print(treap_node *root)
{
    if (root == NULL)
    {
        return;
    }
    treap_down(root);
    treap_print(root->l_child);
    printf("%d ", root->val);
    treap_print(root->r_child);
}

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

int n, m;
int rec_l, rec_r;

int main()
{
#ifdef LOCAL_TIME
    ll start_time_ = clock();
#endif
#ifdef READ_FILE
    freopen("3223.in", "r", stdin);
#ifndef STD_DEBUG
    freopen("3223.out", "w", stdout);
#endif
#endif
#ifdef READ_FREAD
    //fread(fread_string, 1, MAXS, stdin);
#endif
    srand(rand_base);
    init_memory();
    read(n);
    read(m);
    treap_insert(n);
#ifdef LOCAL_DEBUG
    treap_checker();
    printf("n");
#endif
    for (int i = 0; i < m; i++)
    {
        read(rec_l);
        read(rec_r);
        treap_reverse(rec_l, rec_r);
#ifdef LOCAL_DEBUG
        treap_checker();
        printf("n");
#endif
    }
    treap_print(head);
#ifdef LOCAL_TIME
    printf("nrun time: %lld msn", clock() - start_time_);
#endif
#ifdef READ_FILE
    fclose(stdin);
#ifndef STD_DEBUG
    fclose(stdout);
#endif
#endif
    return 0;
}