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
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; }