第一道区间翻转的Splaytree题,其实和线段树差不多的,标记一下,该down的时候down就行了,记录每个数在伸展树中的下标然后从根到节点push down下去。不过有一个小错误倒是让我调了好久,我是加了两个边界点-1的,这样子比较好处理区间,找到那个数后Splay到根,然后要标记下左边的数,如果直接root->ch[1]->mark ^= 1会把-1也翻转,而我刚开始直接翻转所以各种出错。所以还是应该要把要翻转的区间旋转到keytree也就是root->ch[1]->ch[0],最后mark下。
#include
#include
using namespace std;
#define lson x->ch[0]
#define rson x->ch[1]
#define ket (root->ch[1]->ch[0])
const int maxn = 100000+10;
struct NODE {
NODE *pre, *ch[2];
int id, sz, mark, val;
void down() {
if(mark) {
swap(ch[0], ch[1]);
if(ch[0]->pre) ch[0]->mark ^= 1;
if(ch[1]->pre) ch[1]->mark ^= 1;
mark = 0;
}
}
void up() {
sz = ch[0]->sz + ch[1]->sz + 1;
}
};
struct PP {
int val, id, pos;
bool operator < (const PP &a) const {
if(val == a.val) return id < a.id;
return val < a.val;
}
}a[maxn], b[maxn];
struct Splaytree {
int top;
NODE node[maxn], *null, *root;
void Rotate(NODE *x, int c) {
NODE *y = x->pre;
y->down(); x->down();
y->ch[!c] = x->ch[c];
if(x->ch[c] != null) x->ch[c]->pre = y;
x->pre = y->pre;
if(y->pre != null) y->pre->ch[y->pre->ch[1]==y] = x;
x->ch[c] = y; y->pre = x;
y->up();
}
void Splay(NODE *x, NODE *go) {
while(x->pre != go) {
if(x->pre->pre == go) Rotate(x, x->pre->ch[0] == x);
else {
NODE *y = x->pre, *z = y->pre;
int f = z->ch[1] == y;
if(y->ch[f] == x) Rotate(y, !f);
else Rotate(x, f);
Rotate(x, !f);
}
}
x->up();
if(go == null) root = x;
}
void RTO(int k, NODE *go) {
NODE *x = root;
x->down();
while(lson->sz != k) {
if(lson->sz > k) x = lson;
else{
k -= lson->sz + 1;
x = rson;
}
x->down();
}
Splay(x, go);
}
NODE *newnode(int c, NODE *f) {
NODE *x = &node[++top];
x->val = c;
x->pre = f; x->id = top;
x->sz = 1; x->mark = 0;
lson = rson = null;
return x;
}
NODE *build(int l, int r, NODE *f) {
if(l > r) return null;
int mid = (l+r)/2;
NODE *x = newnode(a[mid].val, f);
a[mid].pos = x->id;
lson = build(l, mid-1, x);
rson = build(mid+1, r, x);
x->up();
return x;
}
void init(int n) {
null = &node[0];
null->sz = null->id = null->mark = 0;
top = 0;
root = newnode(-1, null);
root->ch[1] = newnode(-1, root);
ket = build(1, n, root->ch[1]);
root->ch[1]->up(); root->up();
}
void find_path(NODE *x) {
if(x == null) return ;
find_path(x->pre);
x->down();
}
int deal(int pos) {
NODE *x = &node[pos];
find_path(x->pre);
Splay(x, null);
int ret = lson->sz-1;
RTO(0, null);
RTO(ret+1, root);
ket->mark ^= 1;
RTO(ret, null);
RTO(ret+2, root);
ket = null;
root->ch[1]->up(); root->up();
return ret;
}
void gao(int n) {
for(int i = 1;i <= n; i++)
printf("%d%c", i + deal(a[i].pos), i == n ? '\n' : ' ');
}
}spt;
void solve() {
int n;
while(scanf("%d", &n) == 1 && n) {
for(int i = 1;i <= n; i++) {
scanf("%d", &a[i].val);
a[i].id = i;
}
spt.init(n);
sort(a+1, a+n+1);
spt.gao(n);
}
}
int main() {
solve();
return 0;
}