题目大意:给出一个序列,给出一种排序方式,模拟这种排序方式排序,并输出每次找到的节点的位置。
思路:它让你做什么你就做什么,无非就是个Reverse,很简单。注意一下排序的时候权值相等的情况就行了。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100010 #define INF 0x3f3f3f3f using namespace std; struct SplayTree{ SplayTree *son[2],*father; bool reverse; int size; SplayTree(); bool Check() { return father->son[1] == this; } void Combine(SplayTree *a,bool dir) { a->father = this; son[dir] = a; } void Reverse() { reverse ^= 1; swap(son[0],son[1]); } void PushUp() { size = son[0]->size + son[1]->size + 1; } void PushDown() { if(reverse) { son[0]->Reverse(); son[1]->Reverse(); reverse = false; } } }none,*nil = &none,*root; SplayTree:: SplayTree() { son[0] = son[1] = nil; reverse = false; size = 1; } struct Complex{ int val,pos; SplayTree *a; bool operator <(const Complex &a)const { if(val == a.val) return pos < a.pos; return val < a.val; } void Read(int p) { scanf("%d",&val); pos = p; } }src[MAX]; int cnt; void Pretreatment() { nil->size = 0; nil->son[0] = nil->son[1] = nil->father = nil; } SplayTree *BuildTree(int l,int r) { if(l > r) return nil; int mid = (l + r) >> 1; SplayTree *re = new SplayTree(); src[mid].a = re; re->Combine(BuildTree(l,mid - 1),false); re->Combine(BuildTree(mid + 1,r),true); re->PushUp(); return re; } inline void Rotate(SplayTree *a,bool dir) { SplayTree *f = a->father; f->PushDown(); a->PushDown(); f->son[!dir] = a->son[dir]; f->son[!dir]->father = f; a->son[dir] = f; a->father = f->father; f->father->son[f->Check()] = a; f->father = a; f->PushUp(); if(f == root) root = a; } inline void Splay(SplayTree *a,SplayTree *aim) { while(a->father != aim) { if(a->father->father == aim) Rotate(a,!a->Check()); else if(!a->father->Check()) { if(!a->Check()) Rotate(a->father,true),Rotate(a,true); else Rotate(a,false),Rotate(a,true); } else { if(a->Check()) Rotate(a->father,false),Rotate(a,false); else Rotate(a,true),Rotate(a,false); } } a->PushUp(); } SplayTree *Find(SplayTree *a,int k) { a->PushDown(); if(a->son[0]->size >= k) return Find(a->son[0],k); k -= a->son[0]->size; if(k == 1) return a; return Find(a->son[1],k - 1); } inline void SplaySeg(int x,int y) { x++,y++; Splay(Find(root,x - 1),nil); Splay(Find(root,y + 1),root); } int main() { cin >> cnt; Pretreatment(); for(int i = 1; i <= cnt; ++i) src[i].Read(i); src[0].val = src[cnt + 1].val = INF; root = BuildTree(0,cnt + 1); root->father = nil; sort(src + 1,src + cnt + 1); for(int i = 1; i <= cnt; ++i) { Splay(src[i].a,nil); printf("%d%c",root->son[0]->size," \n"[i == cnt]); SplaySeg(i,root->son[0]->size); root->son[1]->son[0]->Reverse(); } return 0; }