Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 3411    Accepted Submission(s): 923


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
  1.  
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
  1.  
Case 1:
3
5
8
Case 2:
Case 3:
3
6

题意:给你一个长为n的序列,第i个数的编号是i,有3个操作,1:把编号为x的数放到序列最前面;2:询问编号为x的数的位置;3:询问第x个位置上的数的编号。

思路:因为n很大(1e8)所以要先离散化,我们把询问的数字都保存下来,变为一个号数的区间 ,然后其他区间都缩成一个点,那么区间的长度最大就为2*10^5了。然后我们先按照位置建立splay,接着就是是play的经典操作了。

下面写了两种程序,第一种是每次找到编号x的数对应的节点,然后再算,第二种是预先用map映射编号x对应的节点,本质是一样的。

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<math.h>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<string>
  10. #include<bitset>
  11. #include<algorithm>
  12. using namespace std;
  13. #define lson th<<1
  14. #define rson th<<1|1
  15. typedef long long ll;
  16. typedef long double ldb;
  17. #define inf 99999999
  18. #define pi acos(-1.0)
  19. #define maxn 200050
  20. #define Key_value ch[ch[root][1]][0]
  21. pair<int,int>question[maxn];
  22. int tot,pos[maxn],s[maxn],e[maxn],qishi[maxn];
  23. int t;
  24. int cnt,rt;
  25. int pre[maxn],ch[maxn][2],sz[maxn],num[maxn];
  26. void Treaval(int x) {
  27. if(x) {
  28. Treaval(ch[x][0]);
  29. printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d , num= %2d \n",x,ch[x][0],ch[x][1],pre[x],sz[x],num[x]);
  30. Treaval(ch[x][1]);
  31. }
  32. }
  33. void debug() {printf("%d\n",rt);Treaval(rt);}
  34. void newnode(int &x,int father,int qujian)
  35. {
  36. x=qujian; //为了方便,这里树上节点的编号就是区间的编号
  37. pre[x]=father;ch[x][0]=ch[x][1]=0;
  38. sz[x]=num[x]=e[x]-s[x]+1;
  39. }
  40. void pushup(int x)
  41. {
  42. sz[x]=sz[ch[x][0] ]+sz[ch[x][1] ]+num[x];
  43. }
  44. void build(int &x,int l,int r,int father)
  45. {
  46. if(l>r)return;
  47. int mid=(l+r)/2;
  48. newnode(x,father,mid);
  49. build(ch[x][0],l,mid-1,x);
  50. build(ch[x][1],mid+1,r,x);
  51. pushup(x);
  52. }
  53. void init()
  54. {
  55. cnt=rt=0;
  56. pre[rt]=ch[rt][0]=ch[rt][1]=sz[rt]=0;
  57. build(rt,1,t,0);
  58. }
  59. void rotate(int x,int p)
  60. {
  61. int y=pre[x];
  62. ch[y][!p]=ch[x][p];
  63. pre[ch[x][p] ]=y;
  64. if(pre[y])ch[pre[y] ][ch[pre[y] ][1]==y ]=x;
  65. pre[x]=pre[y];
  66. ch[x][p]=y;
  67. pre[y]=x;
  68. pushup(y);pushup(x);
  69. }
  70. void splay(int x,int goal)
  71. {
  72. while(pre[x]!=goal){
  73. if(pre[pre[x] ]==goal){
  74. rotate(x,ch[pre[x]][0]==x);
  75. }
  76. else{
  77. int y=pre[x];int z=pre[y];
  78. int p=ch[pre[y] ][0]==y;
  79. if(ch[y][p]==x )rotate(x,!p);
  80. else rotate(y,p);
  81. rotate(x,p);
  82. }
  83. }
  84. if(goal==0)rt=x;
  85. pushup(x);
  86. }
  87. int get_kthjiedian(int &x,int k)
  88. {
  89. int t1=sz[ch[x][0] ]+1;
  90. int t2=sz[ch[x][0] ]+num[x];
  91. if(k>=t1 && k<=t2)return x;
  92. if(k<t1)return get_kthjiedian(ch[x][0],k);
  93. if(k>t2)return get_kthjiedian(ch[x][1],k-t2 );
  94. }
  95. int get_min(int r)
  96. {
  97. while(ch[r][0])
  98. {
  99. r = ch[r][0];
  100. }
  101. return r;
  102. }
  103. int get_kthweizhi(int r,int k)
  104. {
  105. int t = sz[ch[r][0]];
  106. if(k <= t)return get_kthweizhi(ch[r][0],k);
  107. else if(k <= t + num[r]) return s[r] + k - t - 1;
  108. else return get_kthweizhi(ch[r][1],k - t - num[r]);
  109. }
  110. void del()
  111. {
  112. if(ch[rt][0]==0 ){
  113. rt=ch[rt][1];
  114. pre[rt]=0;
  115. }
  116. else{
  117. int y=ch[rt][0];
  118. int x=ch[rt][1];
  119. while(ch[y][1]){
  120. y=ch[y][1];
  121. }
  122. splay(y,rt);
  123. ch[y][1]=x;
  124. pre[x]=y;
  125. rt=y;
  126. pre[rt]=0;
  127. pushup(rt);
  128. }
  129. }
  130. int bin(int x)
  131. {
  132. int l = 1, r = t;
  133. while(l <= r)
  134. {
  135. int mid = (l+r)/2;
  136. if(s[mid] <= x && x <= e[mid])return mid;
  137. if(x < s[mid])r = mid-1;
  138. else l = mid+1;
  139. }
  140. return -1;
  141. }
  142. int main()
  143. {
  144. int n,m,i,j,T,c,d,cas=0;
  145. char str[10];
  146. scanf("%d",&T);
  147. while(T--)
  148. {
  149. scanf("%d%d",&n,&m);
  150. tot=0;
  151. for(i=1;i<=m;i++){
  152. scanf("%s%d",str,&c);
  153. if(str[0]=='T')question[i]=make_pair(1,c);
  154. else if(str[0]=='Q')question[i]=make_pair(2,c);
  155. else question[i]=make_pair(3,c);
  156. pos[++tot]=c;
  157. }
  158. pos[++tot]=1;pos[++tot]=n;
  159. sort(pos+1,pos+1+tot);
  160. tot=unique(pos+1,pos+1+tot)-pos-1;
  161. s[1]=e[1]=pos[1];
  162. t=1;
  163. for(i=2;i<=tot;i++){
  164. if(pos[i]-pos[i-1]>1){
  165. t++;s[t]=pos[i-1]+1;e[t]=pos[i]-1;
  166. }
  167. t++;s[t]=e[t]=pos[i];
  168. }
  169. init();
  170. int qujian;
  171. printf("Case %d:\n",++cas);
  172. for(i=1;i<=m;i++){
  173. c=question[i].first;d=question[i].second;
  174. if(c==1){
  175. int r=bin(d);
  176. splay(r,0);
  177. del();
  178. splay(get_min(rt),0); //这里必须直接把删除的节点放到根节点上,不然会T额。。
  179. ch[r][0] = 0;
  180. ch[r][1] = rt;
  181. pre[rt] = r;
  182. rt = r;
  183. pre[rt] = 0;
  184. num[rt]=e[rt]-s[rt]+1;
  185. pushup(rt);
  186. }
  187. if(c==2){
  188. qujian=bin(d);
  189. splay(qujian,0);
  190. printf("%d\n",sz[ch[rt][0] ]+1);
  191. }
  192. else if(c==3){
  193. printf("%d\n",get_kthweizhi(rt,d));
  194. }
  195. }
  196. }
  197. return 0;
  198. }

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<math.h>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<string>
  10. #include<bitset>
  11. #include<algorithm>
  12. using namespace std;
  13. #define lson th<<1
  14. #define rson th<<1|1
  15. typedef long long ll;
  16. typedef long double ldb;
  17. #define inf 99999999
  18. #define pi acos(-1.0)
  19. #define maxn 900050
  20. #define Key_value ch[ch[root][1]][0]
  21. pair<int,int>question[maxn];
  22. int tot,pos[maxn],s[maxn],e[maxn],qishi[maxn];
  23. int t;
  24. map<int,int>mp;
  25. map<int,int>::iterator it;
  26. int cnt,rt;
  27. int pre[maxn],ch[maxn][2],sz[maxn],num[maxn];
  28. void Treaval(int x) {
  29. if(x) {
  30. Treaval(ch[x][0]);
  31. printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d , num= %2d \n",x,ch[x][0],ch[x][1],pre[x],sz[x],num[x]);
  32. Treaval(ch[x][1]);
  33. }
  34. }
  35. void debug() {printf("%d\n",rt);Treaval(rt);}
  36. void newnode(int &x,int father)
  37. {
  38. x=++cnt;
  39. pre[x]=father;ch[x][0]=ch[x][1]=0;
  40. }
  41. void pushup(int x)
  42. {
  43. sz[x]=sz[ch[x][0] ]+sz[ch[x][1] ]+num[x];
  44. }
  45. void build(int &x,int l,int r,int father)
  46. {
  47. if(l>r)return;
  48. int mid=(l+r)/2;
  49. newnode(x,father);
  50. sz[cnt]=num[cnt]=e[mid]-s[mid]+1;
  51. qishi[cnt]=s[mid];
  52. if(num[cnt]==1)mp[s[mid]]=cnt;
  53. build(ch[x][0],l,mid-1,x);
  54. build(ch[x][1],mid+1,r,x);
  55. pushup(x);
  56. }
  57. void init()
  58. {
  59. cnt=rt=0;
  60. pre[rt]=ch[rt][0]=ch[rt][1]=sz[rt]=0;
  61. build(rt,1,t,0);
  62. }
  63. void rotate(int x,int p)
  64. {
  65. int y=pre[x];
  66. ch[y][!p]=ch[x][p];
  67. pre[ch[x][p] ]=y;
  68. if(pre[y])ch[pre[y] ][ch[pre[y] ][1]==y ]=x;
  69. pre[x]=pre[y];
  70. ch[x][p]=y;
  71. pre[y]=x;
  72. pushup(y);pushup(x);
  73. }
  74. void splay(int x,int goal)
  75. {
  76. while(pre[x]!=goal){
  77. if(pre[pre[x] ]==goal){
  78. rotate(x,ch[pre[x]][0]==x);
  79. }
  80. else{
  81. int y=pre[x];int z=pre[y];
  82. int p=ch[pre[y] ][0]==y;
  83. if(ch[y][p]==x )rotate(x,!p);
  84. else rotate(y,p);
  85. rotate(x,p);
  86. }
  87. }
  88. if(goal==0)rt=x;
  89. pushup(x);
  90. }
  91. int get_kthjiedian(int &x,int k)
  92. {
  93. int t1=sz[ch[x][0] ]+1;
  94. int t2=sz[ch[x][0] ]+num[x];
  95. if(k>=t1 && k<=t2)return x;
  96. if(k<t1)return get_kthjiedian(ch[x][0],k);
  97. if(k>t2)return get_kthjiedian(ch[x][1],k-t2 );
  98. }
  99. int get_kthweizhi(int &x,int k)
  100. {
  101. int t1=sz[ch[x][0] ]+1;
  102. int t2=sz[ch[x][0] ]+num[x];
  103. if(k>=t1 && k<=t2){
  104. int ans=qishi[x]+k-t1;
  105. splay(x,0);
  106. return ans;
  107. }
  108. else if(k<t1)return get_kthweizhi(ch[x][0],k);
  109. else return get_kthweizhi(ch[x][1],k-t2 );
  110. }
  111. void del()
  112. {
  113. if(ch[rt][0]==0 ){
  114. rt=ch[rt][1];
  115. pre[rt]=0;
  116. }
  117. else{
  118. int y=ch[rt][0];
  119. int x=ch[rt][1];
  120. while(ch[y][1]){
  121. y=ch[y][1];
  122. }
  123. splay(y,rt);
  124. ch[y][1]=x;
  125. pre[x]=y;
  126. rt=y;
  127. pre[rt]=0;
  128. pushup(rt);
  129. }
  130. }
  131. int get_min(int x)
  132. {
  133. int r=x;
  134. while(ch[r][0]){
  135. r=ch[r][0];
  136. }
  137. return r;
  138. }
  139. int main()
  140. {
  141. int n,m,i,j,T,c,d,cas=0;
  142. char str[10];
  143. scanf("%d",&T);
  144. while(T--)
  145. {
  146. scanf("%d%d",&n,&m);
  147. tot=0;
  148. for(i=1;i<=m;i++){
  149. scanf("%s%d",str,&c);
  150. if(str[0]=='T')question[i]=make_pair(1,c);
  151. else if(str[0]=='Q')question[i]=make_pair(2,c);
  152. else question[i]=make_pair(3,c);
  153. pos[++tot]=c;
  154. }
  155. pos[++tot]=1;pos[++tot]=n;
  156. sort(pos+1,pos+1+tot);
  157. tot=unique(pos+1,pos+1+tot)-pos-1;
  158. s[1]=e[1]=pos[1];
  159. t=1;
  160. for(i=2;i<=tot;i++){
  161. if(pos[i]-pos[i-1]>1){
  162. t++;s[t]=pos[i-1]+1;e[t]=pos[i]-1;
  163. }
  164. t++;s[t]=e[t]=pos[i];
  165. }
  166. init();
  167. printf("Case %d:\n",++cas);
  168. for(i=1;i<=m;i++){
  169. c=question[i].first;d=question[i].second;
  170. if(c==1){
  171. int geshu=num[mp[d] ];
  172. int kaishi=qishi[mp[d] ];
  173. splay(mp[d],0);
  174. del();
  175. splay(get_min(rt),0 );
  176. cnt++;
  177. qishi[cnt]=kaishi;
  178. pre[cnt]=0;num[cnt]=geshu;
  179. pre[rt]=cnt;
  180. ch[cnt][0]=0;ch[cnt][1]=rt;
  181. rt=cnt;
  182. mp[d]=cnt;
  183. pushup(rt);
  184. }
  185. if(c==2){
  186. splay(mp[d],0);
  187. printf("%d\n",sz[ch[rt][0] ]+1);
  188. }
  189. else if(c==3){
  190. printf("%d\n",get_kthweizhi(rt,d));
  191. }
  192. }
  193. }
  194. return 0;
  195. }

hdu3436 Queue-jumpers(Splay)的更多相关文章

  1. POJ - 3481 splay板子

    Double Queue 默写splay板子 很多细节问题... #include<cstdio> #include<iostream> using namespace std ...

  2. HDU-3436 Queue-jumpers 树状数组 | Splay tree删除,移动

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3436 树状数组做法<猛戳> Splay tree的经典题目,有删除和移动操作.首先要离散化 ...

  3. 【POJ3481】【splay】Double Queue

    Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest ...

  4. POJ 3481Double Queue Splay

    #include<stdio.h> #include<string.h> ; ],data[N],id[N],fa[N],size,root; void Rotate(int ...

  5. HDU 4441 Queue Sequence(splay)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:一个数列,三种操作:(1)插入:找到没在当前数列中的最小的正整数i,将其插在位置p之后,并 ...

  6. codeforces 38G - Queue splay伸展树

    题目 https://codeforces.com/problemset/problem/38/G 题意: 一些人按顺序进入队列,每个人有两个属性,地位$A$和能力$C$ 每个人进入时都在队尾,并最多 ...

  7. POJ-3481 Double Queue (splay)

    The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped w ...

  8. HDU 3436 Queue-jumpers (splay tree)

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  9. 【splay】文艺平衡树 BZOJ 3223

    Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3  ...

随机推荐

  1. Flutter 基础组件:文本、字体样式

    // 文本.字体样式 import 'package:flutter/material.dart'; class TextFontStyle extends StatelessWidget { // ...

  2. Nginx 安装与配置教程

    标签: Nginx Linux Windows 配置 描述: Ubuntu 下以及 Windows 下 Nginx 的配置:配置详解:有关 Nginx 如何配置 Nginx 在 Ubuntu 下的安装 ...

  3. .NET斗鱼直播弹幕客户端(2021)

    .NET斗鱼直播弹幕客户端(2021) 离之前更新的两篇<.NET斗鱼直播弹幕客户端>已经有一段时间,近期有许多客户向我反馈刚好有这方面的需求,但之前的代码不能用了--但网上许多流传的No ...

  4. paramunittest参数化测试基础

    samples: import paramunittestimport unittest@paramunittest.parametrized( (10,20), (30,40), # (100,20 ...

  5. 【Web】实现动态文章列表

    简单记录 -慕课网- 步骤二:动态文章列表效果 实现这个 一个网页中常见的文章列表效果. 怎么实现文章列表案例 分解一波,CSS来改变样式 标题标签 HTML的无序列表 去掉项目符号 符号所占空间 列 ...

  6. 使用K8s的一些经验和体会

    坑 Java应用程序的奇怪案例 ​ 在微服务和容器化方面,工程师倾向于避免使用 Java,这主要是由于 Java 臭名昭著的内存管理.但是,现在情况发生了改变,过去几年来 Java 的容器兼容性得到了 ...

  7. 【Linux】md5sum 生产所有文件的md5值,并对照目标文件是否相同

    现在加入有很多很多文件需要测试md5,想看下是否都传输成功了,如何批量生成文件的md5并且逐条对照呢? 下面来简单介绍下 md5sum这个命令有一个选项"-c" 这个选项的意思是c ...

  8. 【Oracle】delete表后commit后怎么找回,方法

    有些时候,不小心删除了一些需要的表,而且数据库不能停止,只能一直运行下去,这样的话很麻烦 下面介绍的方法就是删除表后通过时间戳后者scn找回删除的数据 模拟实验环境: 创建一个新表 SQL> c ...

  9. ctfhub技能树—web前置技能—http协议—响应包源代码

    打开靶机环境 查看网页是一个贪吃蛇小游戏 根据提示查看源码 发现flag 至此HTTP协议结束

  10. IP2188中文资料书

    IP2188 是一款集成 12 种.用于 USB 输出端口的快充协议 IC,支持 USB 端口充电协议.支持 11种快充协议,包括 USB TypeC PD2.0/PD3.0/PPS DFP,HVDC ...