这道题的splay没有权值,其偏序关系在建完树之后就确定了,所以翻转操作直接交换俩个孩子的指针即可,因为没有权值,也就不用去修改,这样很简单的就改变了该子树的偏序关系,而且可以使用懒惰标记,每次只要把该值所对应的节点旋转到树根然后显示root->size+i(i为该节点排完序后位置,因为每次都会删除排好序的的节点,所以是+i),因为树没有权值,就算我们把每个节点都增加一个域来记录其所对应的数,由于树并不是按该值大小作为关系的,所以也就无法高效的进行查找了,为了解决这个问题,我们在建树时就记录每个数所对应节点的指针,之后直接把该指针所对应节点直接splay到根即可,要小心因为这次的节点不是从上到下select出来的,也就没有把其所有祖先的状态push_down下来,所以splay该指针之前要先回溯到根,然后依次push_dwon下来,即sweep函数(一开始没加开栈的预处理,导致stack overflow了,为了保险最好还是改成迭代的形式)需要注意的是为了方便我们添加了俩个卫兵节点,一个是最小,一个是最大,而进行翻转时,不能改变这俩个节点的关系,所以要确保要翻转的子树中没有这俩个卫兵节点,详细见代码注释
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <utility>
#include <ctime>
#pragma comment(linker, "/STACK:102400000,102400000") //开栈
using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::getline;
using std::make_pair;
using std::greater;
const int MAXN(100010);
struct SPLAY_TREE
{
struct NODE
{
int reverse;
int size;
NODE *fa;
NODE *ch[2];
};
NODE pool[MAXN];
NODE *rear, *root, *NIL;
int cnt;
void newnode(NODE *&sour, NODE *f)
{
rear->size = 1;
rear->reverse = 0;
rear->ch[0] = rear->ch[1] = NIL;
rear->fa = f;
sour = rear++;
}
void init()
{
NIL = pool;
NIL->fa = NIL->ch[0] = NIL->ch[1] = NIL;
NIL->size = 0;
NIL->reverse = 0;
rear = pool+1;
newnode(root, NIL);
}
void push_down(NODE *sour)
{
if(sour->reverse)
{
sour->ch[0]->reverse ^= 1;
sour->ch[1]->reverse ^= 1;
swap(sour->ch[0], sour->ch[1]);
sour->reverse = 0;
}
}
void push_up(NODE *sour)
{
sour->size = sour->ch[0]->size+sour->ch[1]->size+1;
}
void rotate(NODE *sour, int flag)
{
NODE *f = sour->fa;
push_down(f);
push_down(sour);
f->ch[!flag] = sour->ch[flag];
sour->ch[flag]->fa = f;
sour->fa = f->fa;
if(f->fa != NIL)
f->fa->ch[f->fa->ch[1] == f] = sour;
sour->ch[flag] = f;
f->fa = sour;
push_up(f);
}
void splay(NODE *sour, NODE *goal)
{
push_down(sour);
while(sour->fa != goal)
{
if(sour->fa->fa == goal)
rotate(sour, sour->fa->ch[0] == sour);
else
{
NODE *f = sour->fa;
int flag = f->fa->ch[0] == f;
if(f->ch[flag] == sour)
rotate(sour, !flag);
else
rotate(f, flag);
rotate(sour, flag);
}
}
push_up(sour);
if(goal == NIL)
root = sour;
}
NODE *extreme(NODE *sour, int flag)
{
push_down(sour);
while(sour->ch[flag] != NIL)
{
sour = sour->ch[flag];
push_down(sour);
}
return sour;
}
NODE *insert()
{
NODE *sour = extreme(root, 1);
newnode(sour->ch[1], sour);
splay(sour->ch[1], NIL);
return root;
}
void sweep(NODE *sour)
{
if(sour == NIL)
return;
sweep(sour->fa);
push_down(sour);
}
int find(NODE *sour)
{
sweep(sour);
splay(sour, NIL);
int ret = sour->ch[0]->size;
NODE *p1, *p2;
p1 = extreme(sour->ch[0], 0); // 防止卫兵节点翻转
splay(p1, NIL); // 防止卫兵节点翻转
splay(sour, root); // 防止卫兵节点翻转
sour->ch[0]->reverse ^= 1;
splay(sour, NIL);
p1 = extreme(sour->ch[0], 1);
p2 = extreme(sour->ch[1], 0);
splay(p1, NIL);
splay(p2, root);
p2->ch[0] = NIL;
push_up(p2);
push_up(p1);
return ret;
}
};
SPLAY_TREE spt;
struct ELE
{
int num, rank;
SPLAY_TREE::NODE *ptr;
bool operator < (const ELE &op)
{
if(num == op.num)
return rank < op.rank;
else
return num < op.num;
}
};
ELE ele[MAXN];
int main()
{
int n;
while(scanf("%d", &n), n)
{
spt.init();
for(int i = 0; i < n; ++i)
{
scanf("%d", &ele[i].num);
ele[i].rank = i;
ele[i].ptr = spt.insert();
}
spt.insert();
sort(ele, ele+n);
bool print_s(false);
for(int i = 0; i < n; ++i)
{
if(print_s)
printf(" ");
printf("%d", spt.find(ele[i].ptr)+i);
print_s = true;
}
printf("\n");
}
return 0;
}