hdu 3436 splay树+离散化*
来源:互联网 发布:unity3d 画笔涂鸦 编辑:程序博客网 时间:2024/05/17 03:41
Queue-jumpers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3139 Accepted Submission(s): 848
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.
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.
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
39 5Top 1Rank 3Top 7Rank 6Rank 86 2Top 4Top 57 4Top 5Top 2Query 1Rank 6
Sample Output
Case 1:358Case 2:Case 3:36
Author
wzc1989
Source
2010 ACM-ICPC Multi-University Training Contest(1)——Host by FZU
/*hdu 3436 splay树+离散化*本来以为很好做的,写到中途发现10^8,GG然后参考了下,把操作不用的区间缩点离散化处理然后就是删除点,感觉自己开始写的太麻烦了,将要删除的点移动到根,如果没有儿子直接删掉,否则将右树的最小点移到ch[r][1]使右树没有左子树,然后把根的左树接到右树上hhh-2016-02-20 22:22:22*/#include <functional>#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <map>#include <cmath>using namespace std;typedef long long ll;typedef long double ld;#define key_value ch[ch[root][1]][0]const int maxn = 200010;int ch[maxn][2];int pre[maxn],key[maxn],siz[maxn],num[maxn];int root,tot,cnt,n,TOT;int posi[maxn];char qry[maxn][10];int op[maxn];int te[maxn];int s[maxn],e[maxn];void Treaval(int x) { if(x) { Treaval(ch[x][0]); printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d num= %2d \n",x,ch[x][0],ch[x][1],pre[x],siz[x],key[x],num[x]); Treaval(ch[x][1]); }}void debug() {printf("%d\n",root);Treaval(root);}void push_up(int r){ int lson = ch[r][0],rson = ch[r][1]; siz[r] = siz[lson] + siz[rson] + num[r];}void push_down(int r){}void inOrder(int r){ if(!r)return; inOrder(ch[r][0]); printf("%d ",key[r]); inOrder(ch[r][1]);}void NewNode(int &r,int far,int k){ r = ++tot; posi[k] = r; key[r] = k; pre[r] = far; ch[r][0] = ch[r][1] = 0; siz[r] = num[r] = e[k]-s[k]+1;}void rotat(int x,int kind){ int y = pre[x]; push_down(y); push_down(x); ch[y][!kind] = ch[x][kind]; pre[ch[x][kind]] = y; if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y] = x; pre[x] = pre[y]; ch[x][kind] = y; pre[y] = x; push_up(y);}void build(int &x,int l,int r,int far){ if(l > r) return ; int mid = (l+r) >>1; NewNode(x,far,mid); build(ch[x][0],l,mid-1,x); build(ch[x][1],mid+1,r,x); push_up(x);}void splay(int r,int goal){ push_down(r); while(pre[r] != goal) { if(pre[pre[r]] == goal) { push_down(pre[r]); push_down(r); rotat(r,ch[pre[r]][0] == r); } else { push_down(pre[pre[r]]); push_down(pre[r]); push_down(r); int y = pre[r]; int kind = ch[pre[y]][0] == y; if(ch[y][kind] == r) { rotat(r,!kind); rotat(r,kind); } else { rotat(y,kind); rotat(r,kind); } } } push_up(r); if(goal == 0) root = r;}int Bin(int x){ int l = 0,r = TOT-1; while(l<=r) { int mid=(l+r)>>1; if(s[mid]<=x&&e[mid]>=x) return mid; if(e[mid]<x) l=mid+1; else r=mid-1; }}int get_min(int r){ push_down(r); while(ch[r][0]) { r = ch[r][0]; push_down(r); } return r;}int get_kth(int r,int k){ int t = siz[ch[r][0]]; if(k<=t) return get_kth(ch[r][0],k); else if(k<=t+num[r]) return s[key[r]]+(k-t)-1; else return get_kth(ch[r][1],k-t-num[r]);}void delet(){ if(ch[root][0] == 0 || ch[root][1] == 0) { root = ch[root][0] + ch[root][1]; pre[root] = 0; return; } int k = get_min(ch[root][1]); splay(k,root); ch[ch[root][1]][0] = ch[root][0]; root = ch[root][1]; pre[ch[root][0]] = root; pre[root] = 0; push_up(root);}int top(int t){ int r = Bin(t); r = posi[r]; splay(r,0); delet(); splay(get_min(root),0); ch[r][0] = 0; ch[r][1] = root; pre[root] = r; root = r; pre[root] = 0; push_up(root);// debug();}int Query(int x){ int r = Bin(x); r = posi[r]; splay(r,0); return siz[ch[r][0]]+1;}int get_rank(int x,int k){ int t = siz[ch[x][0]]; if(k <= t) return get_rank(ch[x][0],k); else return get_rank(ch[x][1],k-t);}void ini(int n){ tot = root = 0; ch[root][0] = ch[root][1] = pre[root] = siz[root] = num[root] = 0 ; build(root,0,n-1,0); push_up(ch[root][1]); push_up(root); //inOrder(root);}int main(){ int q,T; int cas =1; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&q) ; if(n == -1 && q == -1) break; int tcn = 0; printf("Case %d:\n",cas++); for(int i =1; i <= q; i++) { scanf("%s%d",qry[i],&op[i]); if(qry[i][0] == 'T' || qry[i][0] == 'Q') te[tcn++] = op[i]; } te[tcn++] = n; te[tcn++] = 1; sort(te,te+tcn); TOT= 0; s[TOT] = te[0],e[TOT] = te[0],TOT++; for(int i = 1; i < tcn; i++) { if(te[i] != te[i-1] && i) { if(te[i] - te[i-1] > 1) { s[TOT] = te[i-1]+1; e[TOT] = te[i]-1; TOT++; } s[TOT] = te[i]; e[TOT] = te[i]; TOT++; } } ini(TOT); //debug(); for(int i = 1; i <= q; i++) { if(qry[i][0]=='T') top(op[i]); else if(qry[i][0]=='Q') printf("%d\n", Query(op[i])); else printf("%d\n",get_kth(root,op[i])); } //debug(); } return 0;}
0 0
- hdu 3436 splay树+离散化*
- Splay树 + 离散化 —— HDU 3436 Queue-jumpers
- HDU 3436 Queue-jumpers Splay+离散化
- HDU 3436 Queue-jumpers splay 离散化 模拟
- HDU3436[离散化splay]
- hdu3436Queue-jumpers(splay+离散化)
- 【BZOJ2827】千山鸟飞绝 离散化+splay
- 【Splay】【离散化】hdu3436 Queue-jumpers
- HDU-3436 Queue-jumpers(Splay树)
- HDU 3436 splay
- 【splay】hdu 3436
- 【splay树】hdu 3487
- HDU 1890(Splay树)
- hdu 1890 splay树
- 【BZOJ1125】【POI2008】Poc 原名:Train hash+离散化+平衡树(splay)
- HDU 3436 Queue-jumpers(SplayTree+离散化)
- hdu(4325)线段树+离散化+lazy
- HDU 4325 离散化 + 线段树
- Android群英传笔记——第二章:Android开发工具新接触
- Python 正则表达式(模式匹配)
- jQuery之获取标签
- iOS多线程
- java单例模式singleton回顾,如何实现单例模式
- hdu 3436 splay树+离散化*
- uboot环境变量的讲解
- Yii2-权限控制RBAC-实例篇(三)
- Java中遍历删除List多个元素
- Scala在挖财的应用实践
- yunfile高级会员帐号获取器V1.0绿色版
- SendTs2Ip 将TS流发送到IP网络上的小工具(源码)
- Lua 编写快速排序算法
- POJ 2828 Buy Tickets(线段树)