BZOJ1552 机器排序
之前的无旋treap的merge函数有些错误,现已修改
1 #include<cstdio> 2 #include<iostream> 3 #include<vector> 4 #include<algorithm> 5 #include<cstring> 6 using namespace std; 7 const int MAXN=100000+10; 8 struct NODE{ 9 NODE *ls,*rs; 10 int v,r,s,rev,minn; 11 NODE(int v):v(v){minn=v;ls=rs=NULL;s=1;rev=0;r=rand();} 12 #define size(x) ((x)?(x->s):0) 13 void pushdown(){ 14 if(rev%2){ 15 if(ls){ 16 ls->rev++; 17 swap(ls->ls,ls->rs); 18 } 19 if(rs){ 20 rs->rev++; 21 swap(rs->ls,rs->rs); 22 } 23 } 24 rev=0; 25 } 26 void mt(){ 27 int t,a,b=0x3f3f3f3f,c=0x3f3f3f3f; 28 s=1+size(ls)+size(rs); 29 a=v; 30 if(ls) b=ls->minn; 31 if(rs) c=rs->minn; 32 t=min(a,min(b,c)); 33 if(t == a) minn=v; 34 if(t == b) minn=ls->minn; 35 if(t == c) minn=rs->minn; 36 } 37 }; 38 struct DATA{ 39 int v,id; 40 }a[MAXN]; 41 int b[MAXN]; 42 NODE *root; 43 typedef pair<NODE*,NODE*> droot; 44 int n; 45 int cmp(DATA a,DATA b){ 46 if(a.v < b.v || (a.v == b.v && a.id < b.id)) return 1; 47 return 0; 48 } 49 NODE *merge(NODE *a,NODE *b){ 50 if(!a){b->mt();return b;} 51 if(!b){a->mt();return a;}//这里有错误,现已修改 52 a->pushdown();b->pushdown(); 53 if(a->r < b->r){ 54 a->rs=merge(a->rs,b); 55 a->mt(); 56 return a; 57 } 58 else { 59 b->ls=merge(a,b->ls); 60 b->mt(); 61 return b; 62 } 63 } 64 droot split(NODE *x,int k){ 65 if(!x) return droot(NULL,NULL); 66 droot y;x->pushdown(); 67 if(k <= size(x->ls)){ 68 y=split(x->ls,k); 69 x->ls=y.second; 70 x->mt(); 71 y.second=x; 72 } 73 else { 74 y=split(x->rs,k-size(x->ls)-1); 75 x->rs=y.first; 76 x->mt(); 77 y.first=x; 78 } 79 return y; 80 } 81 82 void init(){ 83 root=NULL; 84 } 85 86 int i,j,ps; 87 NODE *t; 88 droot x,y; 89 int main(){ 90 freopen("roboticsort.in","r",stdin); 91 freopen("roboticsort.out","w",stdout); 92 while(scanf("%d",&n) == 1 && n){ 93 init(); 94 for(int i=1;i<=n;i++){ 95 scanf("%d",&a[i].v); 96 a[i].id=i; 97 } 98 sort(a+1,a+1+n,cmp); 99 for(int i=1;i<=n;i++) b[a[i].id]=i; 100 for(int i=1;i<=n;i++){ 101 t=NULL; 102 t=new NODE(b[i]); 103 root=merge(root,t); 104 } 105 for(int i=1;i<=n;i++){ 106 t=NULL; 107 x=split(root,i-1); 108 t=x.second; 109 ps=i; 110 while(t->v != t->minn){ 111 t->pushdown(); 112 if(t->ls && t->ls->minn == t->minn) t=t->ls; 113 else ps+=size(t->ls)+1,t=t->rs; 114 } 115 ps+=size(t->ls); 116 if(i < n) printf("%d ",ps); 117 else printf("%d\n",ps); 118 //翻转 119 y=split(x.second,ps-i+1); 120 y.first->rev++; 121 swap(y.first->ls,y.first->rs); 122 y.first->mt(); 123 x.second=merge(y.first,y.second); 124 root=merge(x.first,x.second); 125 } 126 } 127 return(0); 128 }