伸展树的经典操作,注意pushdown的位置就好了。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 100005 #define maxm 400005 #define eps 1e-10 #define mod 1000000009 #define INF 99999999 #define lowbit(x) (x&(-x)) #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL; //typedef int LL; using namespace std; struct point { int number, v; }po[maxn]; struct node { int s, v, minv, flip; node *ch[2]; int cmp(int x) { if(x == ch[0]->s+1) return -1; if(x > ch[0]->s+1) return 1; else return 0; } void maintain(void) { s = ch[0]->s + ch[1]->s + 1; minv = v; minv = min(minv, ch[0]->minv); minv = min(minv, ch[1]->minv); } void pushdown(void) { if(!flip) return; swap(ch[0], ch[1]); ch[0]->flip^=1; ch[1]->flip^=1; flip = 0; } }*null, *root; int n; void rotate(node* &o, int d) { node *k = o->ch[d^1]; o->ch[d^1] = k->ch[d], k->ch[d] = o; o->maintain(), k->maintain(), o = k; } void splay(node* &o, int k) { o->pushdown(); int d = o->cmp(k); if(d == -1) return; if(d == 1) k -= o->ch[0]->s+1; node *p = o->ch[d]; p->pushdown(); int d2 = p->cmp(k); int k2 = (d2 == 0 ? k : k - p->ch[0]->s - 1); if(d2 != -1) { splay(p->ch[d2], k2); if(d == d2) rotate(o, d^1); else rotate(o->ch[d], d); } rotate(o, d^1); } node* merge(node* left, node* right) { splay(left, left->s); left->ch[1] = right; left->maintain(); return left; } void split(node* o, int k, node* &left, node* &right) { splay(o, k); right = o->ch[1]; o->ch[1] = null; left = o; left->maintain(); } int find(node* o, int k) { o->pushdown(); if(k == o->v) return o->ch[0]->s+1; if(k == o->ch[0]->minv) return find(o->ch[0], k); else return o->ch[0]->s+1+find(o->ch[1], k); } void init(void) { null = new node; null->s = 0; null->v = null->minv = INF; null->ch[0] = null->ch[1] = NULL; root = new node; root->s = 1; root->v = root->minv = INF; root->ch[0] = root->ch[1] = null; root->maintain(); } int cmp1(point a, point b) { if(a.v == b.v) return a.number < b.number; else return a.v < b.v; } int cmp2(point a, point b) { return a.number < b.number; } void read(void) { for(int i = 1; i <= n; i++) { scanf("%d", &po[i].v); po[i].number = i; } sort(po+1, po+n+1, cmp1); for(int i = 1; i <= n; i++) po[i].v = i; sort(po+1, po+n+1, cmp2); } void build(void) { node *p; for(int i = 1; i <= n; i++) { p = new node; p->flip = 0; p->ch[0] = root; p->ch[1] = null; p->v = po[i].v; root = p; root->maintain(); } } void debug(node* o) { if(o->ch[0] != null) debug(o->ch[0]); printf("AA %d %d BB\n", o->v, o->minv); if(o->ch[1] != null) debug(o->ch[1]); } void work(void) { node *left, *right, *o, *mid; for(int i = 1; i <= n; i++) { int tmp = find(root, i); printf("%d%c", tmp+i-2, i == n ? '\n' : ' '); split(root, tmp, o, right); split(o, tmp-1, left, mid); root = left; split(root, 1, left, o); o->flip^=1; root = merge(merge(left, o), right); if(root != null) root->maintain(); delete mid; } } int main(void) { while(scanf("%d", &n), n!=0) { init(); read(); build(); work(); } return 0; }