题意:给你一个序列,用机器排序,机器每一次旋转一个区间达到排序效果,问你每一需要旋转的位置。
解题思路: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 ",k); 120 for(int i = 1;i <= 6; i++) 121 printf("%d ",sz[i]); 122 printf(" ");*/ 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 ",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(" "); 215 } 216 return 0; 217 }