题目中只有一种操作,把一段区间翻转加到序列后面。。伸展树虽然在区间合并和区间会破坏序列的绝对关系,但是在各种操作中序列的中序遍历是不变的。。。因此我们可以维护一颗伸展树。。然后打上lazy标记,最后求一下最终序列就行了。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 805 #define maxm 400005 #define eps 1e-10 #define mod 1000000009 #define INF 99999999 #define lowbit(x) (x&(-x)) #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL; //typedef int LL; using namespace std; struct node { int s, v, flip; node *ch[2]; int cmp(int x) { if(x == ch[0]->s+1) return -1; if(x > ch[0]->s+1) return 1; else return 0; } void maintain(void) { s = ch[0]->s + ch[1] ->s + 1; } void pushdown(void) { if(!flip) return; swap(ch[0], ch[1]); ch[0]->flip^=1; ch[1]->flip^=1; flip = 0; } }*null, *root; int n, m; void init(int x) { null = new node; null->s = null->v = null->flip = 0; null->ch[0] = null->ch[1] = NULL; root = new node; root->v = root->flip = 0, root->ch[0] = root->ch[1] = null; root->maintain(); node *p; for(int i = 1; i <= n; i++) { p = new node; p->v = i, p->flip = 0; p->ch[0] = root, p->ch[1] = null; root = p, root->maintain(); } } void rotate(node* &o, int d) { node *k = o->ch[d^1]; o->ch[d^1] = k->ch[d], k->ch[d] = o; o->maintain(), k->maintain(), o = k; } void splay(node* &o, int k) { o->pushdown(); int d = o->cmp(k); if(d == 1) k -= o->ch[0]->s + 1; if(d != -1) { node *p = o->ch[d]; p->pushdown(); int d2 = p->cmp(k); int k2 = (d2 == 0 ? k : k - p->ch[0]->s - 1); if(d2 != -1) { splay(p->ch[d2], k2); if(d == d2) rotate(o, d^1); else rotate(o->ch[d], d); } rotate(o, d^1); } } node* merge(node *left, node *right) { splay(left, left->s); left->ch[1] = right; left->maintain(); return left; } void split(node* o, int k, node* &left, node* &right) { splay(o, k); right = o->ch[1]; o->ch[1] = null; left = o; left->maintain(); } void solve(node* &o) { o->pushdown(); if(o->ch[0] != null) solve(o->ch[0]); if(o->v != 0) printf("%d\n", o->v); if(o->ch[1] != null) solve(o->ch[1]); } void work(void) { int a, b; while(m--) { scanf("%d%d", &a, &b); node *left, *right, *mid, *o; split(root, a, left, o); split(o, b-a+1, mid, right); mid->flip^=1; root = merge(merge(left, right), mid); } } int main(void) { while(scanf("%d%d", &n, &m)!=EOF) { init(n); work(); solve(root); } return 0; }