链接 : http://acm.hdu.edu.cn/showproblem.php?pid=1890
下传翻转标记的时候要特别注意
每次将第i个数到第i大的数之间的数翻转,然后删除第i大的数
/*
区间翻转,注意标记的下传
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define L ch[x][0]
#define R ch[x][1]
#define KT (ch[ ch[rt][1] ][0])
const int maxn = 100010;
int cmp(pair<int,int> a,pair<int,int> b){
if(a.first!=b.first) return a.first<b.first;
return a.second < b.second;
}
struct SplayTree {
int sz[maxn];
int ch[maxn][2];
int pre[maxn];
int rt,top;
inline void down(int x){
if(flip[x]) {
flip[ L ] ^= 1;
flip[ R ] ^= 1;
swap(L,R);
flip[x]=0;
}
}
inline void up(int x){
sz[x]=1+sz[ L ] + sz[ R ];
}
inline void Rotate(int x,int f){
int y=pre[x];
down(y);
down(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;
up(y);
}
inline void Splay(int x,int goal){//将x旋转到goal的下面
down(x);//防止pre[x]就是目标点,下面的循环就进不去了,x的信息就传不下去了
while(pre[x] != goal){
down(pre[pre[x]]); down(pre[x]);down(x);//在旋转之前需要先下传标记,因为节点的位置可能会发生改变
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);
}
}
up(x);
if(goal==0) rt=x;
}
inline void RTO(int k,int goal){//将第k位数旋转到goal的下面
int x=rt;
down(x);
while(sz[ L ]+1 != k) {
if(k < sz[ L ] + 1 ) x=L;
else {
k-=(sz[ L ]+1);
x = R;
}
down(x);
}
Splay(x,goal);
}
void vist(int x){
if(x){
printf("结点%2d : 左儿子 %2d 右儿子 %2d %2d flip:%d\n",x,L,R,val[x],flip[x]);
vist(L);
vist(R);
}
}
void Newnode(int &x,int c,int f){
x=++top;flip[x]=0;
L = R = 0; pre[x] = f;
sz[x]=1; val[x]=c;
}
inline void build(int &x,int l,int r,int f){
if(l>r) return ;
int m=l+r>>1;
Newnode(x,num[id[m]].first,f);
mp[id[m]]=x;
build(L , l , m-1 , x);
build(R , m+1 , r , x);
pre[x]=f;
up(x);
}
inline void init(int n){
ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;
rt=top=0; flip[0]=0; val[0]=0;
for(int i=1;i<=n;i++) {
scanf("%d",&num[i].first);
num[i].second=i;
}
sort(num+1,num+n+1,cmp);
for(int i=1;i<=n;i++) id[num[i].second] = i;
build(rt,1,n,0);
}
void Del(){
int t=rt;
if(ch[rt][1]) {
rt=ch[rt][1];
RTO(1,0);
ch[rt][0]=ch[t][0];
if(ch[rt][0]) pre[ch[rt][0]]=rt;
}
else rt=ch[rt][0];
pre[rt]=0;
up(rt);
}
void solve(int n){
for(int i=1;i<=n;i++) {
Splay(mp[i],0);
printf("%d",i+sz[ ch[rt][0] ]);
flip[ch[rt][0]]^=1;
Del();
printf(i==n ? "\n": " ");
}
}
pair<int,int> num[maxn];
int id[maxn];
int mp[maxn];
int flip[maxn];
int val[maxn];
}spt;
int main()
{
int n;
while(scanf("%d",&n),n){
spt.init(n);
spt.solve(n);
}
return 0;
}