传送门biu~biu~
对原序列建一棵平衡树,用
Findi
F
i
n
d
i
记录第i小的物品在平衡树上的哪个位置。
#include<bits/stdc++.h>
using namespace std;
int n;
struct data{int x,id,rnk;}a[100005];
bool cmp(data a,data b){return a.x<b.x || (a.x==b.x && a.id<b.id);}
bool cmp_id(data a,data b){return a.id<b.id;}
struct Node{
Node *fa,*ch[2];
int siz;
bool rev_mark;
Node();
inline int dir(){
if(fa->ch[0]==this) return 0;
if(fa->ch[1]==this) return 1;
return -1;
}
inline void rev();
inline void pushdown();
inline void maintain();
}*null=new Node,*root,*Find[100005];
Node :: Node(){
siz=null?1:0;
fa=ch[0]=ch[1]=null;
}
inline void Node :: maintain(){
if(this==null) return;
siz=ch[0]->siz+ch[1]->siz+1;
}
inline void Node :: rev(){
if(this==null) return;
swap(ch[0],ch[1]);
rev_mark^=1;
}
inline void Node :: pushdown(){
if(this==null) return;
if(!rev_mark) return;
rev_mark=0;
ch[0]->rev();ch[1]->rev();
}
void To_pushdown(Node *o){
if(o->fa!=null) To_pushdown(o->fa);
o->pushdown();
}
void buildtree(Node *father,Node *&o,int l,int r){
if(l>r) return;
o=new Node(); o->fa=father;
if(l==r){
Find[a[l].rnk]=o;
return;
}
int mid=(l+r)>>1; Find[a[mid].rnk]=o;
buildtree(o,o->ch[0],l,mid-1);
buildtree(o,o->ch[1],mid+1,r);
o->maintain();
}
inline void Rotate(Node *o,int d){
Node *x=o->ch[d^1];
x->ch[d]->fa=o; o->ch[d^1]=x->ch[d];
x->fa=o->fa; o->fa->ch[o->dir()]=x;
x->ch[d]=o; o->fa=x;
o->maintain(); x->maintain();
}
inline void Splay(Node *o,Node *u){
To_pushdown(o);
while(o->fa!=u){
if(o->fa->fa!=u){
if(o->dir()==o->fa->dir()) Rotate(o->fa->fa,o->dir()^1);
}
Rotate(o->fa,o->dir()^1);
}
if(u==null) root=o;
}
Node *Kth(Node *o,int k){
o->pushdown();
if(o->ch[0]->siz+1==k) return o;
if(k<=o->ch[0]->siz) return Kth(o->ch[0],k);
return Kth(o->ch[1],k-o->ch[0]->siz-1);
}
inline void Reverse(int l,int r){
Node *x=Kth(root,l),*y=Kth(root,r+2);
Splay(x,null);Splay(y,x);
y->ch[0]->rev();
}
int main(){
scanf("%d",&n);
for(int i=2;i<=n+1;++i) scanf("%d",&a[i].x),a[i].id=i;
sort(a+2,a+n+2,cmp);
for(int i=2;i<=n+1;++i) a[i].rnk=i-1;
sort(a+2,a+n+2,cmp_id);
buildtree(null,root,1,n+2);
for(int i=1;i<=n;++i){
Splay(Find[i],null);
int Rank=root->ch[0]->siz;
if(i!=n)printf("%d ",Rank);
else printf("%d",Rank);
Reverse(i,Rank);
}
}