[LuoguP3391] 文艺平衡树

题目背景

 

题目描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列。

其中需要提供以下操作:翻转一个区间,例如原有序序列是 5\ 4\ 3\ 2\ 15 4 3 2 1,翻转区间是 [2,4][2,4] 的话,结果是 5\ 2\ 3\ 4\ 15 2 3 4 1。

输入格式

第一行两个正整数 n,mn,m,表示序列长度与操作个数。序列中第 ii 项初始为 ii。
接下来 mm 行,每行两个正整数 l,rl,r,表示翻转的区间。

输出格式

输出一行 nn 个正整数,表示原始序列经过 mm 次变换后的结果。

输入输出样例

输入 #1
5 3
1 3
1 3
1 4
输出 #1
4 3 2 1 5

说明/提示

【数据范围】
对于 100\%100% 的数据,1 \le n, m \leq 1000001n,m100000,1 \le l \le r \le n1lrn。

 
以前是用的splay
这次用的fhq treap 好写太多了
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000000 + 10;
struct Tree{
    int val, size, lc, rc, pri;
    bool tag;
    Tree(){
        size = 0;
    }
    Tree(int val): val(val){
        size = 1;
        lc = rc = 0;
        tag = false;
        pri = rand();
    }
}t[maxn];
int root = 0, tcnt = 0;
inline void pushdown(int x){
    if(t[x].tag){
        swap(t[x].lc, t[x].rc);
        t[t[x].lc].tag ^= 1;
        t[t[x].rc].tag ^= 1;
        t[x].tag = false;
    }
}
inline void pushup(int x){
    t[x].size = t[t[x].lc].size + t[t[x].rc].size + 1;
}
void split(int x, int &a, int &b, int k){
    if(!x){
        a = b = 0;
        return;
    }
    pushdown(x);
    if(k <= t[t[x].lc].size){
        b = x;
        split(t[x].lc, a, t[b].lc, k);
    }
    else{
        a = x;
        split(t[x].rc, t[a].rc, b, k - t[t[x].lc].size - 1);
    }
    pushup(x);
}
inline int newnode(int val){
    t[++tcnt] = Tree(val);
    return tcnt;
}
void merge(int &x, int a, int b){
    if(!a || !b){
        x = a | b;
        return;
    }
    pushdown(a); pushdown(b);
    if(t[a].pri < t[b].pri){
        x = a;
        merge(t[x].rc, t[a].rc, b);
    }
    else{
        x = b;
        merge(t[x].lc, a, t[b].lc);
    }
    pushup(x);
}
void bl(int x){
    if(!x) return;
    pushdown(x);
    bl(t[x].lc);
    cout << t[x].val << ' ';
    bl(t[x].rc);
}
int main(){
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        merge(root, root, newnode(i));
    }
    int l, r, a, b, c;
    for(int i = 1; i <= m; i++){
        cin >> l >> r;
        split(root, a, b, l - 1);
        split(b, b, c, r - l + 1);
        t[b].tag = 1;
        merge(b, a, b);
        merge(root, b, c);
    }
    bl(root); putchar('\n');
    return 0;
}

 

posted @ 2019-12-27 15:39  Elder_Giang  阅读(120)  评论(0编辑  收藏  举报