Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<iostream>
- #include<stdio.h>
- #include<assert.h>
- #include<string.h>
- #include<time.h>
- #include<stdlib.h>
- #include<math.h>
- #include<string>
- #include<sstream>
- #include<map>
- #include<set>
- #include<queue>
- #include<stack>
- #include<vector>
- #include<algorithm>
- #pragma comment(linker, "/STACK:16777216")
- #define pb push_back
- #define ppb pop_back
- #define mp make_pair
- #define all(x) (x).begin(),(x).end()
- #define sz(x) (int)(x).size()
- #define LL long long
- #define bit __builtin_popcountll
- using namespace std;
- template<class T> inline T sqr(T x) { return x * x; }
- typedef pair<int, int> pii;
- const double eps = 1e-9;
- const double pi = acos(-1.0);
- const int maxn = (int)1e5 + 10;
- struct node
- {
- int y;
- int cnt;
- bool rev;
- node *p;
- node *l;
- node *r;
- node() : y(rand() % 1000000000), cnt(1), rev(false), p(NULL), l(NULL), r(NULL) {}
- };
- struct belt
- {
- int x;
- int id;
- };
- typedef node *pnode;
- int cnt(pnode T)
- {
- return T ? T -> cnt : 0;
- }
- void upd_cnt(pnode T)
- {
- if (T) T -> cnt = cnt(T -> l) + cnt(T -> r) + 1;
- }
- void push(pnode T)
- {
- if (T && T -> rev)
- {
- T -> rev = false;
- swap(T -> l,T -> r);
- if (T -> l) T -> l -> rev ^= true;
- if (T -> r) T -> r -> rev ^= true;
- }
- }
- void split(pnode T, pnode &L, pnode &R, int key, int add = 0)
- {
- push(T);
- if (!T) return void(L = R = NULL);
- int cur_key = cnt(T -> l) + add;
- if (cur_key >= key)
- {
- split(T -> l,L,T -> l,key,add);
- if (T -> l) T -> l -> p = T;
- if (L) L -> p = NULL;
- R = T;
- } else
- {
- split(T -> r,T -> r,R,key,add + cnt(T -> l) + 1);
- if (T -> r) T -> r -> p = T;
- if (R) R -> p = NULL;
- L = T;
- }
- upd_cnt(T);
- }
- void merge(pnode &T, pnode L, pnode R)
- {
- push(L);
- push(R);
- if (!L || !R) T = L ? L : R; else
- if (L -> y > R -> y)
- {
- merge(L -> r,L -> r,R);
- if (L -> r) L -> r -> p = L;
- T = L;
- } else
- {
- merge(R -> l,L,R -> l);
- if (R -> l) R -> l -> p = R;
- T = R;
- }
- upd_cnt(T);
- }
- pnode order[maxn],T,st[maxn];
- belt A[maxn];
- int p[maxn],pp[maxn];
- bool cmp(int i, int j)
- {
- return A[i].x < A[j].x || A[i].x == A[j].x && A[i].id < A[j].id;
- }
- void insert(int x)
- {
- pnode P = new node();
- order[pp[x]] = P;
- merge(T,T,P);
- }
- int pos(pnode T)
- {
- int c = 0;
- while(T)
- {
- st[c++] = T;
- T = T -> p;
- }
- int add = 0;
- for(int i = c - 1; i > 0; i--)
- {
- push(st[i]);
- if (st[i] -> l == st[i - 1])
- {
- continue;
- } else
- {
- add += 1 + cnt(st[i] -> l);
- }
- }
- push(st[0]);
- add += cnt(st[0] -> l);
- return add + 1;
- }
- void swapper(int l, int r)
- {
- pnode L,MID,R;
- split(T,L,R,l);
- split(R,MID,R,r - l + 1);
- if (MID) MID -> rev ^= true;
- merge(T,L,MID);
- merge(T,T,R);
- split(T,L,T,1);
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- #endif
- srand(time(0));
- int n;
- while(true)
- {
- scanf("%d",&n);
- if (n == 0) break;
- T = NULL;
- for(int i = 0; i < n; i++)
- {
- int x;
- scanf("%d",&x);
- A[i].x = x;
- A[i].id = i;
- p[i] = i;
- }
- sort(p,p + n,cmp);
- for(int i = 0; i < n; i++)
- pp[p[i]] = i;
- for(int i = 0; i < n; i++)
- insert(i);
- for(int i = 0; i < n; i++)
- {
- int position = pos(order[i]);
- printf("%d ",position + i);
- swapper(0,position - 1);
- }
- puts("");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement