洛谷【P3391】文艺平衡树(fhq Treap区间操作)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
struct node{
    int l, r, val, key, size;
    bool reverse;
}tree[maxn];
std::mt19937 rnd(233);
int n, m, tot, root;

inline int read(){
    int s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}

inline void print(int x){
    if(x < 0) x = ~x + 1, putchar('-');
    if(x > 9) print(x / 10);
    putchar(x % 10 + '0');
}

inline int newnode(int val){
    tree[++tot].val = val;
    tree[tot].key = rnd();
    tree[tot].size = 1;
    return tot;
}

inline void update(int now){
    tree[now].size = tree[tree[now].l].size + tree[tree[now].r].size + 1;
}

inline void pushdown(int now){
    swap(tree[now].l, tree[now].r);
    tree[tree[now].l].reverse ^= 1;
    tree[tree[now].r].reverse ^= 1;
    tree[now].reverse = false;
}

void split(int now, int siz, int &x, int &y){
    if(!now) x = y = 0;
    else{
        if(tree[now].reverse) pushdown(now);
        if(tree[tree[now].l].size < siz)
            x=now, split(tree[now].r, siz-tree[tree[now].l].size - 1, tree[now].r, y);
        else
            y=now, split(tree[now].l, siz, x, tree[now].l);
        update(now);
    }
}

int merge(int x, int y){
    if(!x || !y) return x + y;
    if(tree[x].key < tree[y].key){
        if(tree[x].reverse) pushdown(x);
        tree[x].r = merge(tree[x].r, y);
        update(x);
        return x;
    }
    else{
        if(tree[y].reverse) pushdown(y);
        tree[y].l = merge(x, tree[y].l);
        update(y);
        return y;
    }
}

void reverse(int l, int r){
    int x, y, z;
    split(root, l - 1, x, y);
    split(y, r - l + 1, y, z);
    tree[y].reverse ^= 1;
    root = merge(merge(x, y), z);
}

void ldr(int now){
    if(!now) return;
    if(tree[now].reverse) pushdown(now);
    ldr(tree[now].l);
    print(tree[now].val);
    putchar(' ');
    ldr(tree[now].r);
}

int main(int argc, char const *argv[])
{
    n = read(), m = read();
    for(int i = 1; i <= n; i++)
        root = merge(root, newnode(i));
    while(m--){
        int l, r;
        l = read(), r = read();
        reverse(l, r);
    }
    ldr(root);
}
/*
* ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
* │Esc│   │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│  ┌┐    ┌┐    ┌┐
* └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘  └┘    └┘    └┘
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
* │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │Num│ / │ * │ - │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
* │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │   │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
* │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter  │               │ 4 │ 5 │ 6 │   │
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
* │ Shift  │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│  Shift   │     │ ↑ │     │ 1 │ 2 │ 3 │   │
* ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
* │ Ctrl│ Win│ Alt│         Space         │ Alt│ Win│Menu│Ctrl│ │ ← │ ↓ │ → │ │   0   │ . │←─┘│
* └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
*/

全部评论

相关推荐

醒工硬件:如果你想投硬件,可以考虑这么改: 1.个人荣誉没太有保留价值,除非一页凑不满 2.主修课程太多了,可以考虑删减一部分,或者分成硬件和嵌入式2个简历,侧重点不一样 3.个人技能放到学习经历下面,项目经历上面。学习一下AD画板,你有基础一两周也差不多学会了,面试官问你就说你会(总不能拉你实操吧),公司里一般用AD和Cadence比较多,AD好上手一些。增加常用仪器工具说明,例如示波器、信号发生器、电子负载、烙铁、风枪等 4.项目,项目可以多换换行,挤在一起不好阅读。可以说下红外那边用什么接口,蓝牙那边用什么接口,用了哪些关键技术点,多用术语。如果你投硬件,就增加项目1描述比重,降低项目2描述比重
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务