题意:给你一个序列,用机器排序,机器每一次旋转一个区间达到排序效果,问你每一需要旋转的位置。

解题思路:splay 区间旋转。

解题代码:

  1 // File Name: hdu1890.1.cpp
  2 // Author: darkdream
  3 // Created Time: 2015年04月04日 星期六 21时28分31秒
  4 
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #include<limits.h>
 25 #define LL long long
 26 #define keyTree (ch[ch[root][1]][0])
 27 using namespace std;
 28 const int maxn = 100005; 
 29 int flag = 0 ; 
 30 
 31 struct SplayTree{
 32     int sz[maxn];
 33     int ch[maxn][2];
 34     int pre[maxn];
 35     int root ,top1,top2;
 36     int ss[maxn],que[maxn];
 37     struct node{
 38       int i,si,val;
 39     }num[maxn];
 40     static bool cmp(node a,node b)
 41     {
 42       return a.i < b.i; 
 43     }
 44     inline void Rotate(int x, int f){
 45          int y = pre[x];
 46          push_down(y);
 47          push_down(x);
 48          ch[y][!f] = ch[x][f];
 49          pre[ch[x][f]] = y ;
 50          pre[x] = pre[y];
 51          if(pre[x])  ch[pre[y]][ch[pre[y]][1] == y] = x; 
 52          ch[x][f] = y ; 
 53          pre[y] = x; 
 54          push_up(y);
 55     }
 56     inline void Splay(int x, int goal){
 57         push_down(x);
 58         while(pre[x] != goal){
 59             if(pre[pre[x]] == goal){
 60                Rotate(x,ch[pre[x]][0] == x);
 61             }else{
 62                 int y = pre[x],z = pre[y];
 63                 int f = (ch[z][0] == y );
 64                 if(ch[y][f] == x)
 65                     Rotate(x,!f),Rotate(x,f);
 66                 else Rotate(y,f),Rotate(x,f);
 67             }
 68         }
 69         push_up(x);
 70         if(goal == 0 ) root = x; 
 71     }
 72     inline void RotateTo(int k ,int goal){
 73         int x = root;
 74         push_down(x);
 75         while(sz[ch[x][0]] != k)
 76         {
 77             if(k < sz[ch[x][0]]){
 78                 x = ch[x][0];
 79             }else{
 80                 k-= (sz[ch[x][0]] +1);
 81                 x = ch[x][1];
 82             }
 83             push_down(x);
 84         }
 85         Splay(x,goal);
 86     }
 87     void print(int x){
 88         if(x == 0 )
 89             return ;
 90         print(ch[x][0]);
 91         printf("%d ",val[x]);
 92         print(ch[x][1]);
 93     }
 94     inline int findK(int mxnum){
 95         int k = 0 ; 
 96         for(int i = root;i != 0 ;)
 97         {
 98             push_down(i);
 99             if(val[i] == mi[root])
100             {
101                k += sz[ch[i][0]] ;
102                RotateTo(0,0);
103                RotateTo(k+1,root);
104                rev[keyTree] ^= 1;
105                RotateTo(0,0);
106                RotateTo(2,root);
107                erase(keyTree);
108                push_up(ch[root][1]);
109                push_up(root);
110                return k ; 
111             }
112             if(mi[ch[i][1]] == mi[root])
113             {
114                 k += sz[ch[i][0]] + 1; 
115                 i = ch[i][1];
116             }
117             else{ 
118                 i = ch[i][0];
119                 /*printf("****%d\n",k);
120                 for(int i = 1;i <= 6; i++)
121                     printf("%d ",sz[i]);
122                 printf("\n");*/
123             }
124         }
125     }
126     inline void erase(int x){
127         int father = pre[x];
128         int head = 0 ,tail =0 ; 
129         for(que[tail++] = x ;head < tail ;head ++){
130            ss[top2 ++ ] = que[head];
131            if(ch[que[head]][0])  que[tail ++] = ch[que[head]][0];
132            if(ch[que[head]][1])  que[tail ++] = ch[que[head]][1];
133         }
134         ch[father][ch[father][1] == x] = 0 ; 
135         push_up(father);
136     }
137 
138     inline void NewNode(int &x,int c){
139         if(top2) x = ss[--top2];
140         else x = ++ top1;
141         ch[x][0] = ch[x][1] = pre[x] = rev[x] = 0 ; 
142         sz[x] = 1; 
143         val[x] = mi[x] = c; 
144     }
145     inline void push_down(int x)
146     {
147        if(rev[x]){
148            swap(ch[x][0],ch[x][1]);
149            rev[ch[x][0]] ^= 1;
150            rev[ch[x][1]] ^= 1;
151            rev[x] = 0;
152        }    
153     }
154     inline void push_up(int x)
155     {
156          sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]];
157          mi[x] = min(val[x],mi[ch[x][0]]) ;    
158          mi[x] = min(mi[x],mi[ch[x][1]]) ;    
159     }
160     inline void makeTree(int &x ,int l ,int r ,int f){
161         if(l > r ) return;
162         int m = (l + r) >> 1; 
163         NewNode(x,num[m].val);
164     //    printf("%d %d\n",x,num[m]);
165         makeTree(ch[x][0],l,m-1,x);
166         makeTree(ch[x][1],m+1,r,x);
167         pre[x] = f; 
168         push_up(x);
169     }
170     static bool cmp2(SplayTree::node a, SplayTree::node b)
171     {
172       return a.si < b.si;
173     }
174     inline void init(int n){
175         ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0 ; 
176         rev[0] = 0; 
177         mi[0] = INT_MAX;
178     
179         root = top1 = top2 = 0 ; 
180 
181         NewNode(root,INT_MAX);
182         NewNode(ch[root][1],INT_MAX);
183         pre[top1] = root;
184         sz[root] = 2; 
185         
186         for(int i = 1 ;i <= n;i ++) 
187         {
188             scanf("%d",&num[i].i);
189             num[i].si = i ; 
190         }
191         stable_sort(num+1,num+n+1,cmp);
192         for(int i = 1;i <= n;i ++)
193         {
194             num[i].val = i; 
195         }
196         sort(num+1,num+n+1,SplayTree::cmp2);
197         makeTree(keyTree,1,n,ch[root][1]);
198         push_up(ch[root][1]);
199         push_up(root);
200     }
201     int mi[maxn];
202     int rev[maxn];
203     int val[maxn];
204 }spt;
205 int n ; 
206 int main(){
207     while(scanf("%d",&n) != EOF && n)
208     {
209         spt.init(n);
210         for(int i = 1;i <= n;i ++)
211         {
212             printf(i == 1?"%d":" %d",i-1+spt.findK(n-i+2));
213         }
214         printf("\n");
215     }
216 return 0;
217 }
View Code

 

posted on 2015-04-06 14:37  dark_dream  阅读(174)  评论(0编辑  收藏  举报