cogs1545 机器排序 splay

链接:http://cogs.pro/cogs/problem/problem.php?pid=1545

题意:一个机器每次只会将一个区间反转使右端点的物品正确到达左端点,求出每次转移的右端点。

维护一个splay,每次操作,把哨兵转到根,右端点后一个到达右儿子,该节点到达这个右儿子的左儿子,标记完成后再转到左子树,扔掉该节点。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 using namespace std;
  5 const int SIZEN=100010,INF=0x7fffffff/2;
  6 class SPLAYTREE{
  7 public:
  8     class NODE{
  9     public:
 10         int key,size;
 11         bool rev;
 12         NODE *f,*lc,*rc;
 13         int mx;
 14         NODE(int k){key=mx=k;size=1;rev=0;}
 15     }*Nil,*Root,*left,*right;
 16     NODE *newNODE(int key){
 17         NODE *T=new NODE(key);
 18         T->lc=T->rc=T->f=Nil;
 19         return T;
 20     }
 21     void clear(){
 22         Nil=new NODE(INF);
 23         Nil->lc=Nil->rc=Nil->f=Nil;
 24         Nil->size=0;
 25         left=newNODE(INF),right=newNODE(INF);
 26         left->size++,left->rc=right,right->f=left;
 27         Root=left;
 28     }
 29     void pushdown(NODE *T){
 30         if(T->rev){
 31             T->lc->rev^=1,T->rc->rev^=1;
 32             swap(T->lc,T->rc);
 33             T->rev=0;
 34         }
 35     }
 36     void update(NODE *T){
 37         T->size=T->lc->size+T->rc->size+1;
 38         T->mx=min(T->lc->mx,T->rc->mx);
 39         T->mx=min(T->mx,T->key);
 40     }
 41     void zig(NODE *T){
 42         NODE *P=T->f,*rson=T->rc;
 43         pushdown(P->rc),pushdown(T->lc),pushdown(T->rc);
 44         if(Root==P) Root=T;
 45         else (P->f->lc==P)?(P->f->lc=T):(P->f->rc=T);
 46         T->f=P->f,P->f=T;rson->f=P;T->rc=P;P->lc=rson;
 47         update(P);
 48     }
 49     void zag(NODE *T){
 50         NODE *P=T->f,*lson=T->lc;
 51         pushdown(P->lc),pushdown(T->lc),pushdown(T->rc);
 52         if(Root==P) Root=T;
 53         else (P->f->lc==P)?(P->f->lc=T):(P->f->rc=T);
 54         T->f=P->f,P->f=T;lson->f=P;T->lc=P;P->rc=lson;
 55         update(P);
 56     }
 57     void splay(NODE *ANC,NODE *t){
 58         pushdown(t);
 59         if(t==ANC){update(t);return;}
 60         bool reach=false;
 61         while(!reach){
 62             NODE *P=t->f;
 63             if(P==ANC) (P->lc==t)?zig(t):zag(t),reach=true;
 64             else{
 65                 if(P->f==ANC) reach=true;
 66                 if(P->f->lc==P) (P->lc==t)?zig(P):zag(t),zig(t);
 67                 else (P->rc==t)?zag(P):zig(t),zag(t);
 68             }
 69         }
 70         update(t);
 71     }
 72     void insert(int *a,int k){
 73         NODE *t=newNODE(a[1]),*p=t,*q=t;
 74         for(int i=2;i<=k;i++) t=newNODE(a[i]),t->f=p,p->rc=t,p=t;
 75         Root->rc->lc=q,q->f=Root->rc;
 76         splay(Root,p);
 77     }
 78     void select(NODE *ANC,int k){
 79         NODE *t=ANC;
 80         while(true){
 81             pushdown(t);
 82             if(k==t->lc->size+1){
 83                 splay(ANC,t);
 84                 return;
 85             }
 86             if(k<=t->lc->size) t=t->lc;
 87             else k-=t->lc->size+1,t=t->rc;
 88         }
 89     }
 90     void findmin(int k){
 91         NODE *t=Root;
 92         int pos=0;
 93         while(t->key!=t->mx){
 94             pushdown(t);
 95             if(t->lc->mx==t->mx) t=t->lc;
 96             else pos+=t->lc->size+1,t=t->rc;
 97         }
 98         pushdown(t);
 99         pos+=t->lc->size;
100         printf("%d ",pos+k-1);
101         select(Root,1);
102         select(Root->rc,pos+1);
103         select(Root->rc->lc,pos);
104         Root->rc->lc->rev^=1;
105         pushdown(Root->rc->lc);
106         select(Root->rc,2);
107         delete Root->rc->lc;
108         Root->rc->lc=Nil;
109         splay(Root,Root->rc);
110     }
111 }tree;
112 int N;
113 pair<int,int> height[SIZEN];
114 int equh[SIZEN]={0};
115 bool work(void){
116     scanf("%d",&N);
117     if(!N) return false;
118     for(int i=1;i<=N;i++) scanf("%d",&height[i].first),height[i].second=i;
119     sort(height+1,height+1+N);
120     for(int i=1;i<=N;i++) equh[height[i].second]=i;
121     tree.clear();
122     tree.insert(equh,N);
123     for(int i=1;i<=N;i++) tree.findmin(i);
124     puts("");
125     return true;
126 }
127 int main(){
128     freopen("roboticsort.in","r",stdin);
129     freopen("roboticsort.out","w",stdout);
130     while(work());
131     return 0;
132 }
cogs1545

 

posted @ 2017-08-03 21:12  ccc000111  阅读(230)  评论(0编辑  收藏  举报