BZOJ 3506 CQOI 2014 sorting manipulator Splay
Give a sequence, give a sort method, simulate this sort method, and output the position of each node found.
Idea: it is nothing more than a Reverse to let you do what you do. Pay attention to the case where the weights are equal during sorting.
CODE:
#include
#include
#include
#include #define MAX 100010#define INF 0x3f3f3f3fusing 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;}