原题链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902
伸展树的区间翻转剪切。。。
伸展树的区间翻转剪切。。。
如下:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
const int Max_N = 100010;
struct Node{
int v, s, rev;
Node *pre, *ch[2];
inline void set(int _v = -1, int _s = 0, Node *p = NULL){
v = _v, s = _s, rev = 0;
pre = ch[0] = ch[1] = p;
}
inline void push_up(){
s = ch[0]->s + ch[1]->s + 1;
}
inline void update(){
rev ^= 1;
std::swap(ch[0], ch[1]);
}
inline void push_down(){
if (rev != 0){
rev ^= 1;
ch[0]->update();
ch[1]->update();
}
}
};
struct SplayTree{
int N = 0;
Node *tail, *root, *null, stack[Max_N];
void init(int n){
N = n, tail = &stack[0];
null = tail++;
null->set();
root = newNode(-1);
root->ch[1] = newNode(-1);
root->ch[1]->pre = root;
Node *x = built(1, n);
root->ch[1]->ch[0] = x;
x->pre = root->ch[1];
root->ch[1]->push_up();
root->push_up();
}
inline Node *newNode(int v){
Node *p = tail++;
p->set(v, 1, null);
return p;
}
Node *built(int l, int r){
if (l > r) return null;
int mid = (l + r) >> 1;
Node *p = newNode(mid);
p->ch[0] = built(l, mid - 1);
if (p->ch[0] != null) p->ch[0]->pre = p;
p->ch[1] = built(mid + 1, r);
if (p->ch[1] != null) p->ch[1]->pre = p;
p->push_up();
return p;
}
inline void rotate(Node *x, int c){
Node *y = x->pre;
y->push_down(), x->push_down();
y->ch[!c] = x->ch[c];
x->pre = y->pre;
if (x->ch[c] != null) x->ch[c]->pre = y;
if (y->pre != null) y->pre->ch[y->pre->ch[0] != y] = x;
x->ch[c] = y;
y->pre = x;
y->push_up();
if (y == root) root = x;
}
inline void splay(Node *x, Node *f){
if (x == root) return;
for (; x->pre != f; x->push_down()){
if (x->pre->pre == f){
rotate(x, x->pre->ch[0] == x);
} else {
Node *y = x->pre, *z = y->pre;
if (z->ch[0] == y){
if (y->ch[0] == x)
rotate(y, 1), rotate(x, 1);
else rotate(x, 0), rotate(x, 1);
} else {
if (y->ch[1] == x)
rotate(y, 0), rotate(x, 0);
else rotate(x, 1), rotate(x, 0);
}
}
}
x->push_up();
}
inline Node *select(Node *x, int k){
for (int t = 0; x != null;){
x->push_down();
t = x->ch[0]->s;
if (t == k) break;
else if (k < t) x = x->ch[0];
else k -= t + 1, x = x->ch[1];
}
return x;
}
inline Node *get_range(int l, int r){
splay(select(root, l - 1), null);
splay(select(root, r + 1), root);
return root->ch[1]->ch[0];
}
inline Node *reverse(int l, int r){
Node *x = get_range(l, r);
x->update();
return x;
}
inline void cut_link(int l, int r){
Node *x = reverse(l, r);
root->ch[1]->ch[0] = null;
root->ch[1]->push_up();
root->push_up();
int k = N - r + l - 1;
get_range(1, k);
splay(select(root, k), null);
splay(select(root, k + 1), root);
root->ch[1]->ch[0] = x;
x->pre = root->ch[1];
root->ch[1]->push_up();
root->push_up();
}
inline void travle(Node *x){
if (x != null){
x->push_down();
travle(x->ch[0]);
printf("%d\n", x->v);
travle(x->ch[1]);
}
}
inline void travle(){
get_range(1, N);
Node *x = root->ch[1]->ch[0];
travle(x);
}
}Splay;
int main(){
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w+", stdout);
#endif
int a, b, n, m;
while (~scanf("%d %d", &n, &m)){
Splay.init(n);
while (m--){
scanf("%d %d", &a, &b);
Splay.cut_link(a, b);
}
Splay.travle();
}
return 0;
}