Queue-jumpers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1821 Accepted Submission(s): 425
Problem Description Ponyo and Garfield are waiting outside the box-office for their favorite movie. Because queuing is so boring, that they want to play a game to kill the time. The game is called “Queue-jumpers”. Suppose that there are N people numbered from 1 to N stand in a line initially. Each time you should simulate one of the following operations:
1. Top x :Take person x to the front of the queue
2. Query x: calculate the current position of person x
3. Rank x: calculate the current person at position x
Where x is in [1, N].
Ponyo is so clever that she plays the game very well while Garfield has no idea. Garfield is now turning to you for help.
Input In the first line there is an integer T, indicates the number of test cases.(T<=50)
In each case, the first line contains two integers N(1<=N<=10^8), Q(1<=Q<=10^5). Then there are Q lines, each line contain an operation as said above.
Output For each test case, output “Case d:“ at first line where d is the case number counted from one, then for each “Query x” operation ,output the current position of person x at a line, for each “Rank x” operation, output the current person at position x at a line.
Sample Input 3 9 5 Top 1 Rank 3 Top 7 Rank 6 Rank 8 6 2 Top 4 Top 5 7 4 Top 5 Top 2 Query 1 Rank 6
Sample Output Case 1: 3 5 8 Case 2: Case 3: 3 6
Author wzc1989
Source
2010 ACM-ICPC Multi-University Training Contest(1)——Host by FZU
Recommend zhouzeyong
离散化,
把Top的点提取出来,其余的缩点
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013/8/25 13:28:12 4 File Name :F:\2013ACM练习\专题学习\splay_tree_2\HDU3436.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 21 #define Key_value ch[ch[root][1]][0] 22 const int MAXN = 200010; 23 int pre[MAXN],ch[MAXN][2],size[MAXN]; 24 int num[MAXN];//r结点包含的数的个数 25 int s[MAXN],e[MAXN]; 26 int cnt;//离散分段后的个数 27 int root,tot1; 28 29 //debug部分********************************** 30 void Treavel(int x) 31 { 32 if(x) 33 { 34 Treavel(ch[x][0]); 35 printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d num = %2d s = %2d e = %2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],num[x],s[x],e[x]); 36 Treavel(ch[x][1]); 37 } 38 } 39 void debug() 40 { 41 printf("root:%d\n",root); 42 Treavel(root); 43 } 44 //以上是debug部分************************************** 45 46 47 48 void NewNode(int &r,int father,int k) 49 { 50 r = k; 51 ch[r][0] = ch[r][1] = 0; 52 size[r] = e[k] - s[k] + 1; 53 num[r] = e[k] - s[k] + 1; 54 pre[r] = father; 55 } 56 void push_up(int r) 57 { 58 size[r] = size[ch[r][0]] + size[ch[r][1]] + num[r]; 59 } 60 void push_down(int r) 61 { 62 63 } 64 void Build(int &x,int l,int r,int father) 65 { 66 if(l > r)return; 67 int mid = (l+r)/2; 68 NewNode(x,father,mid); 69 Build(ch[x][0],l,mid-1,x); 70 Build(ch[x][1],mid+1,r,x); 71 push_up(x); 72 } 73 void Init() 74 { 75 root = tot1 = 0; 76 ch[root][0] = ch[root][1] = num[root] = size[root] = pre[root] = 0; 77 Build(root,1,cnt,0); 78 push_up(root); 79 } 80 //旋转,0为左旋,1为右旋 81 void Rotate(int x,int kind) 82 { 83 int y = pre[x]; 84 push_down(y); 85 push_down(x);//先把y的标记下传,在把x的标记下传 86 ch[y][!kind] = ch[x][kind]; 87 pre[ch[x][kind]] = y; 88 if(pre[y]) 89 ch[pre[y]][ch[pre[y]][1]==y] = x; 90 pre[x] = pre[y]; 91 ch[x][kind] = y; 92 pre[y] = x; 93 push_up(y); 94 } 95 //Splay调整,将r结点调整到goal下面 96 void Splay(int r,int goal) 97 { 98 push_down(r); 99 while(pre[r] != goal) 100 { 101 if(pre[pre[r]] == goal) 102 Rotate(r,ch[pre[r]][0]==r); 103 else 104 { 105 int y = pre[r]; 106 int kind = ch[pre[y]][0]==y; 107 if(ch[y][kind] == r) 108 { 109 Rotate(r,!kind); 110 Rotate(r,kind); 111 } 112 else 113 { 114 Rotate(y,kind); 115 Rotate(r,kind); 116 } 117 } 118 } 119 push_up(r); 120 if(goal == 0) root = r; 121 } 122 123 124 int Get_Min(int r) 125 { 126 push_down(r); 127 while(ch[r][0]) 128 { 129 r = ch[r][0]; 130 push_down(r); 131 } 132 return r; 133 } 134 int Get_Max(int r) 135 { 136 push_down(r); 137 while(ch[r][1]) 138 { 139 r = ch[r][1]; 140 push_down(r); 141 } 142 return r; 143 } 144 //删除根结点 145 void Delete() 146 { 147 if(ch[root][0] == 0 || ch[root][1] == 0) 148 { 149 root = ch[root][0] + ch[root][1]; 150 pre[root] = 0; 151 return; 152 } 153 int k = Get_Min(ch[root][1]); 154 Splay(k,root); 155 Key_value = ch[root][0]; 156 root = ch[root][1]; 157 pre[ch[root][0]] = root; 158 pre[root] = 0; 159 push_up(root); 160 } 161 162 int Bin(int x)//二分查找x属于哪一段 163 { 164 int l = 1, r = cnt; 165 while(l <= r) 166 { 167 int mid = (l+r)/2; 168 if(s[mid] <= x && x <= e[mid])return mid; 169 if(x < s[mid])r = mid-1; 170 else l = mid+1; 171 } 172 return -1; 173 } 174 175 //将点x放到最前面 176 void Top(int x) 177 { 178 int r = Bin(x); 179 Splay(r,0); 180 Delete(); 181 Splay(Get_Min(root),0); 182 ch[r][0] = 0; 183 ch[r][1] = root; 184 pre[root] = r; 185 root = r; 186 pre[root] = 0; 187 push_up(root); 188 } 189 int Query(int x) 190 { 191 int r = Bin(x); 192 Splay(r,0); 193 return size[ch[root][0]] + x - s[r] + 1; 194 } 195 int Get_Rank(int r,int k) 196 { 197 int t = size[ch[r][0]]; 198 if(k <= t)return Get_Rank(ch[r][0],k); 199 else if(k <= t + num[r]) return s[r] + k - t - 1; 200 else return Get_Rank(ch[r][1],k - t - num[r]); 201 } 202 char op[MAXN][10]; 203 int qnum[MAXN]; 204 int p[MAXN]; 205 206 int main() 207 { 208 //freopen("in.txt","r",stdin); 209 //freopen("out.txt","w",stdout); 210 int N,Q; 211 int T; 212 scanf("%d",&T); 213 int iCase = 0; 214 while(T--) 215 { 216 iCase++; 217 scanf("%d%d",&N,&Q); 218 int t = 0; 219 for(int i = 0;i < Q;i++) 220 { 221 scanf("%s%d",&op[i],&qnum[i]); 222 if(op[i][0] == 'T') 223 p[t++] = qnum[i]; 224 } 225 p[t++] = 1; 226 p[t++] = N; 227 sort(p,p+t); 228 t = unique(p,p+t) - p; 229 cnt = 0; 230 for(int i = 0;i < t;i++) 231 { 232 if(i > 0 && p[i] - p[i-1] > 1) 233 { 234 cnt++; 235 s[cnt] = p[i-1] + 1; 236 e[cnt] = p[i] - 1; 237 } 238 cnt++; 239 s[cnt] = p[i]; 240 e[cnt] = p[i]; 241 } 242 Init(); 243 // debug(); 244 //continue; 245 printf("Case %d:\n",iCase); 246 for(int i = 0;i < Q;i++) 247 { 248 if(op[i][0] == 'T')Top(qnum[i]); 249 else if(op[i][0] =='Q')printf("%d\n",Query(qnum[i])); 250 else printf("%d\n",Get_Rank(root,qnum[i])); 251 //debug(); 252 } 253 } 254 return 0; 255 }