这道题就是Splay基础的旋转和删点,先将需要删的点的位置记录下来并且按照翻转的先后顺序排序
然后每一次都将该点旋转至根,答案就是左儿子的大小加上i,再将左儿子旋转且将根删除就可以了
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int SIZEN = 100015;
struct elem{
int val,id;
bool operator < (const elem &a)const{
if(val != a.val) return val < a.val;
return id < a.id;
}
};
elem ss[SIZEN];
struct SplayTree{
int ch[SIZEN][2];
int pre[SIZEN];
int sz[SIZEN];
int val[SIZEN];
int top,root;
void exchange(int x){
swap(ch[x][0],ch[x][1]);
}
inline void pushdown(int x){
if(lazy[x]){
lazy[ ch[x][0] ] ^= 1;
lazy[ ch[x][1] ] ^= 1;
exchange(ch[x][0]);
exchange(ch[x][1]);
lazy[x] = 0;
}
}
inline void pushup(int x){
sz[x] = sz[ ch[x][0] ] + sz[ ch[x][1] ] + 1;
}
inline void Rotate(int x,int f){
int y = pre[x];
pushdown(y);
pushdown(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x]) ch[ pre[y] ][ ch[ pre[y] ][1] == y ] = x;
ch[x][f] = y;
pre[y] = x;
pushup(y);
}
inline void Splay(int x,int goal) {
pushdown(x);
while(pre[x] != goal) {
if(pre[pre[x]] == goal) {
Rotate(x , ch[pre[x]][0] == x);
} else {
int y = pre[x] , z = pre[y];
int f = (ch[z][0] == y);
if(ch[y][f] == x) {
Rotate(x,!f);
Rotate(x,f);
} else {
Rotate(y,f);
Rotate(x,f);
}
}
}
pushup(x);
if(goal == 0) root = x;
}
void debug(){
printf("root:%d\n",root);
Travel(root);
}
void Travel(int x){
pushdown(x);
if(ch[x][0]) Travel(ch[x][0]);
printf("node:%d lson:%d rson:%d sz:%d pre:%d val:%d\n",x,ch[x][0],ch[x][1],sz[x],pre[x],val[x]);
if(ch[x][1]) Travel(ch[x][1]);
}
void Newnode(int x){
ch[x][0] = ch[x][1] = 0;
sz[x] = 1;
lazy[x] = 0;
}
inline void init(){
ch[0][0] = ch[0][1] = pre[0] = 0;
sz[0] = lazy[0] = 0;
root = top = 0;
}
inline void build(int &x,int l,int r,int f){
if(l > r) return;
int mid = (l + r) >> 1;
x = mid;
Newnode(x);
build(ch[x][0],l,mid - 1,x);
build(ch[x][1],mid + 1,r,x);
pre[x] = f;
pushup(x);
}
int findmax(int x){
pushdown(x);
while(ch[x][1]){
x = ch[x][1];
pushdown(x);
}
return x;
}
void del(){
int ls,rs;
ls = ch[root][0];rs = ch[root][1];
if(!ls){
root = rs;
pre[ rs ] = 0;
return;
}
int m = findmax(ch[root][0]);
Splay(m,root);
ch[m][1] = rs;
pre[rs] = m;
ch[root][0] = ch[root][1] = 0;
root = m;
pre[root] = 0;
pushup(root);
}
inline int change(int i){
Splay(ss[i].id,0);
int ans = sz[ ch[root][0] ] + i;
lazy[ ch[root][0] ] ^= 1;
exchange(ch[root][0]);
del();
return ans;
}
int num[SIZEN];
int lazy[SIZEN];
};
SplayTree spt;
void solve(int n){
for(int i = 1 ; i <= n ; i++){
scanf("%d",&spt.num[i]);
ss[i].val = spt.num[i];
ss[i].id = i;
}
sort(ss + 1,ss + n + 1);
spt.init();
spt.build(spt.root,1,n,0);
for(int i = 1 ; i < n ; i++)
printf("%d ",spt.change(i));
printf("%d\n",n);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n) solve(n);
}