題意:給定n長的序列
找到其中靠右的最大值 Maxval 所在的位置 x
把[Maxval, x] 翻轉一下。
如此進行n次排序(若Maxval==x, 則翻轉[x,x] 區間(就是類似于無效操作,但是要進行)
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
using namespace std;
#define L(x) tree[x].ch[0]
#define R(x) tree[x].ch[1]
#define Father(x) tree[x].fa
#define Size(x) tree[x].size
#define Val(x) tree[x].val
#define Minv(x) tree[x].minv
#define Filp(x) tree[x].filp
#define ll int
#define inf 10000000
#define N 200005
inline ll Mid(ll x,ll y){return (x+y)>>1;}
struct node{
int ch[2], fa, size;
int val, minv, filp;
}tree[N];
int tot, root;
struct A{
int val, pos;
bool operator<(const A& a)const{
return (val==a.val&&pos<a.pos)||(val<a.val);
}
}a[N];
int n;
node Newnode(int val, int fa, int size){
node E={0,0,fa,size, val, val, 0};
return E;
}
void push_up(int id){
Size(id) = Size(L(id))+Size(R(id))+1;
Minv(id) = min(Minv(L(id)), Minv(R(id)));
Minv(id) = min(Val(id), Minv(id));
}
void push_down(int id){
if(Filp(id))
{
Filp(id) = 0;
Filp(L(id))^=1;
Filp(R(id))^=1;
swap(L(id),R(id));
}
}
void rotate(ll id, ll kind){ //kind為0代表左旋 為1代表右旋
ll y = Father(id);
push_down(id); push_down(y);
Father(tree[id].ch[kind]) = y;
tree[y].ch[kind^1] = tree[id].ch[kind];
if(Father(y))
tree[Father(y)].ch[ R(Father(y))==y ] = id;
Father(id) = Father(y);
tree[id].ch[kind] = y;
Father(y) = id;
push_up(y);
}
void splay(ll id, ll goal){
push_down(id);
while(Father(id)!=goal){
if(Father( Father(id) ) == goal)
rotate(id, L(Father(id)) == id);
else
{
ll y = Father(id);
ll kind = L(Father(y)) == y;
if(tree[y].ch[kind] == id) //共線
{
rotate(id, kind^1);
rotate(id, kind);
}
else
{
rotate(y, kind);
rotate(id,kind);
}
}
}
push_up(id);
if(goal == 0)root = id;
}
void RotateTo(ll k, ll goal){ //把第k個節點伸展到goal下
ll id = root;
push_down(id);
while(Size(L(id))!=k){
if(Size(L(id)) > k)
id = L(id);
else {
k -= (Size(L(id))+1);
id = R(id);
}
push_down(id);
}
splay(id, goal);
}
void Interval(ll l, ll r){
RotateTo(l, 0);
RotateTo(r, root);
}
ll find_min(ll v){
ll id = root;
push_down(id);
while(Val(id)!=v){
id =( (Minv(L(id))==v)?L(id):R(id) );
push_down(id);
}
return id;
}
ll D[N];
int build(ll l, ll r, ll fa){
if(l>r)return 0;
ll mid = Mid(l,r);
ll id = tot;
tree[tot++] = Newnode(D[mid], fa, 1);
L(id) = build(l, mid-1, id);
R(id) = build(mid+1, r, id);
push_up(id);
return id;
}
void init(){
tree[0] = Newnode(inf,0,0);
tot = root = 1;
tree[tot++] = Newnode(inf,0,1);
tree[tot++] = Newnode(inf,R(root),1);
R(root) = tot-1;
L(R(root)) = build(1,n,R(root));
push_up(R(root));
push_up(root);
}
ll getmax(ll id){//找到id這個子樹下的最大值的标号
push_down(id);
while(R(id)){
id = R(id);
push_down(id);
}
return id;
}
void Delroot(){
if(L(root)==0){
root = R(root);
Father(root) = 0;
return;
}
int now = getmax(L(root));
splay(now, root);
int id = root;
root = now;
Father(root) = 0;
R(root) = R(id);
Father(R(id)) = root;
push_up(root);
}
int main(){
ll i, j, u ,v;
while(scanf("%d",&n),n){
for(i=1;i<=n;i++)scanf("%d",&a[i].val), a[i].pos = i;
sort(a+1,a+n+1);
for(i=1;i<=n;i++)D[a[i].pos] = i;
init();
for(i=1;i<=n;i++){
splay(find_min(i),0);
printf("%d", Size(L(root))+i);
Filp(L(root))^=1;
Delroot();
i==n?puts(""):printf(" ");
}
}
return 0;
}