Description

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 

Input

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n 

Output

输出一行n个数字,表示原始序列经过m次变换后的结果 

Sample Input

5 3
1 3
1 3
1 4

Sample Output

4 3 2 1 5

HINT

N,M<=100000

【题目分析】

 模板题。维护rev标记。

 下放标记的地方:$Merge(), Split()$

【CODE】

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
 
const int N = 1e5;
int n, m;
 
struct node{
    node *lc, *rc;
    bool reverse;
    int value, pri, size;
    node(){}
    node(const int &_v) : value(_v), lc(NULL), rc(NULL), pri(rand()), reverse(false) {}
    inline node* update(){
        size = (lc ? lc->size : 0) + (rc ? rc->size : 0) + 1;
        return this;
    }
}tree[N], *root = NULL;
 
inline void pushDown(node *u){
    if(u->reverse){
        if(u->lc) u->lc->reverse ^= 1;
        if(u->rc) u->rc->reverse ^= 1;
        swap(u->lc, u->rc);
        u->reverse = false;
    }
}
 
inline node* Merge(node *u, node *v){
    if(!u) return v;
    if(!v) return u;
    pushDown(u), pushDown(v);
    if(u->pri < v->pri){
        u->rc = Merge(u->rc, v);
        return u->update();
    }
    else{
        v->lc = Merge(u, v->lc);
        return v->update();
    }
}
 
#define sz(u) (u? u->size : 0)
inline void Split(node *u, const int &Kth, node *&L, node *&R){
    if(!u) return (void)(L = R = NULL);
    pushDown(u);
    if(sz(u->lc) < Kth){
        Split(u->rc, Kth - sz(u->lc) - 1, L, R);
        u->rc = NULL, u->update();
        L = Merge(u, L);
    }
    else{
        Split(u->lc, Kth, L, R);
        u->lc = NULL, u->update();
        R = Merge(R, u);
    }
}
 
inline void Split2(node *u, const int &v, node *&L, node *&R){
    if(!u) return (void)(L = R = NULL);
    pushDown(u);
    if(u->value < v){
        Split2(u->rc, v, L, R);
        u->rc = NULL, u->update();
        L = Merge(u, L);
    }
    else{
        Split2(u->lc, v, L, R);
        u->lc = NULL, u->update();
        R = Merge(R, u);
    }
}
inline node* Insert(node *u, int v){
    node *L, *R;
    Split2(u, v, L, R);
    node *ret = new node(v);
    return Merge(Merge(L, ret), R);
}
 
inline void print(node *u){
    if(u->lc) pushDown(u->lc), print(u->lc);
    cout<<u->value<<" ";
    if(u->rc) pushDown(u->rc), print(u->rc);
}
 
inline node* Modify(node *u, int l, int r){
    node *L, *R, *p, *q;
    Split(u, l - 1, L, R);
    Split(R, r - l + 1, p, q);
    p->reverse ^= 1;
    return Merge(L, Merge(p, q));
}
 
int main(){
//  freopen("h.in", "r", stdin);
    cin>>n>>m;
    scanf("\n");
    for(int i = 1; i <= n; i++)
        root = Insert(root, i);
    for(int i = 1; i <= m; i++){
        int a, b;
        cin>>a>>b;
        scanf("\n");
        Modify(root, a, b);
    }
    print(root);
    return 0;
}
View Code

 

相关文章: