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
 
Recommend
zhouzeyong
 

离散化,

把Top的点提取出来,其余的缩点

 /* ***********************************************
Author :kuangbin
Created Time :2013/8/25 13:28:12
File Name :F:\2013ACM练习\专题学习\splay_tree_2\HDU3436.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; #define Key_value ch[ch[root][1]][0]
const int MAXN = ;
int pre[MAXN],ch[MAXN][],size[MAXN];
int num[MAXN];//r结点包含的数的个数
int s[MAXN],e[MAXN];
int cnt;//离散分段后的个数
int root,tot1; //debug部分**********************************
void Treavel(int x)
{
if(x)
{
Treavel(ch[x][]);
printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d num = %2d s = %2d e = %2d\n",x,ch[x][],ch[x][],pre[x],size[x],num[x],s[x],e[x]);
Treavel(ch[x][]);
}
}
void debug()
{
printf("root:%d\n",root);
Treavel(root);
}
//以上是debug部分************************************** void NewNode(int &r,int father,int k)
{
r = k;
ch[r][] = ch[r][] = ;
size[r] = e[k] - s[k] + ;
num[r] = e[k] - s[k] + ;
pre[r] = father;
}
void push_up(int r)
{
size[r] = size[ch[r][]] + size[ch[r][]] + num[r];
}
void push_down(int r)
{ }
void Build(int &x,int l,int r,int father)
{
if(l > r)return;
int mid = (l+r)/;
NewNode(x,father,mid);
Build(ch[x][],l,mid-,x);
Build(ch[x][],mid+,r,x);
push_up(x);
}
void Init()
{
root = tot1 = ;
ch[root][] = ch[root][] = num[root] = size[root] = pre[root] = ;
Build(root,,cnt,);
push_up(root);
}
//旋转,0为左旋,1为右旋
void Rotate(int x,int kind)
{
int y = pre[x];
push_down(y);
push_down(x);//先把y的标记下传,在把x的标记下传
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if(pre[y])
ch[pre[y]][ch[pre[y]][]==y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
//Splay调整,将r结点调整到goal下面
void Splay(int r,int goal)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r]] == goal)
Rotate(r,ch[pre[r]][]==r);
else
{
int y = pre[r];
int kind = ch[pre[y]][]==y;
if(ch[y][kind] == r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
push_up(r);
if(goal == ) root = r;
} int Get_Min(int r)
{
push_down(r);
while(ch[r][])
{
r = ch[r][];
push_down(r);
}
return r;
}
int Get_Max(int r)
{
push_down(r);
while(ch[r][])
{
r = ch[r][];
push_down(r);
}
return r;
}
//删除根结点
void Delete()
{
if(ch[root][] == || ch[root][] == )
{
root = ch[root][] + ch[root][];
pre[root] = ;
return;
}
int k = Get_Min(ch[root][]);
Splay(k,root);
Key_value = ch[root][];
root = ch[root][];
pre[ch[root][]] = root;
pre[root] = ;
push_up(root);
} int Bin(int x)//二分查找x属于哪一段
{
int l = , r = cnt;
while(l <= r)
{
int mid = (l+r)/;
if(s[mid] <= x && x <= e[mid])return mid;
if(x < s[mid])r = mid-;
else l = mid+;
}
return -;
} //将点x放到最前面
void Top(int x)
{
int r = Bin(x);
Splay(r,);
Delete();
Splay(Get_Min(root),);
ch[r][] = ;
ch[r][] = root;
pre[root] = r;
root = r;
pre[root] = ;
push_up(root);
}
int Query(int x)
{
int r = Bin(x);
Splay(r,);
return size[ch[root][]] + x - s[r] + ;
}
int Get_Rank(int r,int k)
{
int t = size[ch[r][]];
if(k <= t)return Get_Rank(ch[r][],k);
else if(k <= t + num[r]) return s[r] + k - t - ;
else return Get_Rank(ch[r][],k - t - num[r]);
}
char op[MAXN][];
int qnum[MAXN];
int p[MAXN]; int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int N,Q;
int T;
scanf("%d",&T);
int iCase = ;
while(T--)
{
iCase++;
scanf("%d%d",&N,&Q);
int t = ;
for(int i = ;i < Q;i++)
{
scanf("%s%d",&op[i],&qnum[i]);
if(op[i][] == 'T')
p[t++] = qnum[i];
}
p[t++] = ;
p[t++] = N;
sort(p,p+t);
t = unique(p,p+t) - p;
cnt = ;
for(int i = ;i < t;i++)
{
if(i > && p[i] - p[i-] > )
{
cnt++;
s[cnt] = p[i-] + ;
e[cnt] = p[i] - ;
}
cnt++;
s[cnt] = p[i];
e[cnt] = p[i];
}
Init();
// debug();
//continue;
printf("Case %d:\n",iCase);
for(int i = ;i < Q;i++)
{
if(op[i][] == 'T')Top(qnum[i]);
else if(op[i][] =='Q')printf("%d\n",Query(qnum[i]));
else printf("%d\n",Get_Rank(root,qnum[i]));
//debug();
}
}
return ;
}

HDU 3436 Queue-jumpers (splay tree)的更多相关文章

  1. HDU 1890 Robotic Sort (splay tree)

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  2. 伸展树(Splay Tree)进阶 - 从原理到实现

    目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...

  3. 数据结构(二) --- 伸展树(Splay Tree)

    文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...

  4. 纸上谈兵:伸展树(splay tree)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...

  5. 平衡树之伸展树(Splay Tree)题目整理

    目录 前言 练习1 BZOJ 3224 普通平衡树 练习2 BZOJ 3223 文艺平衡树 练习3 BZOJ 1588 [HNOI2002]营业额统计 练习4 BZOJ 1208 [HNOI2004] ...

  6. 伸展树(splay tree)

    伸展树的设计思路,鉴于数据访问的局部性(28原则)在实际应用中普遍存在,将按照"最常用者优先"的启发策略.尽管在最坏情况下其单次操作需要 O(n) 时间,但分摊而言仍然 O(log ...

  7. HDU 4441 Queue Sequence(splay)

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

  8. HDU 1890--Robotic Sort(Splay Tree)

    题意:每次找出第i大的数的位置p输出,然后将i~p之间的数反转. 题解:每次把要的区间转成一棵子树,然后更新.因为每次将第i小的数转到了了i,所以k次操作后,可知前k个数一定是最小的那k个数,所以以后 ...

  9. BZOJ 1269: [AHOI2006]文本编辑器editor (splay tree)

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1213  Solved: 454[Submit ...

随机推荐

  1. SQL CAST与CONVERT区别

    CAST 和 CONVERT 将某种数据类型的表达式显式转换为另一种数据类型.CAST 和 CONVERT 提供相似的功能. 语法 使用 CAST: CAST ( expression AS data ...

  2. MySQL 连接本地数据库、远程数据库命令

    一.MySQL 连接本地数据库,用户名为“root”,密码“123”(注意:“-p”和“123” 之间不能有空格) C:/>mysql -h localhost -u root -p123 二. ...

  3. linux下nc提交web报文问题

    1.用wireshark截取访问百度首页拿到的请求数据包: GET /index.php?tn=newbdie_bd_dg&bar= HTTP/1.1 Host: www.baidu.com ...

  4. JavaScript 三个常用对话框

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. java8 - 时间

    import java.time.DayOfWeek; import java.time.Duration; import java.time.Instant; import java.time.Lo ...

  6. Kafka(五)Kafka的API操作和拦截器

    一 kafka的API操作 1.1 环境准备 1)在eclipse中创建一个java工程 2)在工程的根目录创建一个lib文件夹 3)解压kafka安装包,将安装包libs目录下的jar包拷贝到工程的 ...

  7. Spark(三)RDD与广播变量、累加器

    一.RDD的概述 1.1 什么是RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可 ...

  8. 【BZOJ】1061: [Noi2008]志愿者招募

    题解 可能是世界上最裸的一个单纯形 (话说全幺模矩阵是啥我到现在都不知道) 假装我们已经看过了算导,或者xxx的论文,知道了单纯形是怎么实现的 扔一个blog走掉..https://www.cnblo ...

  9. linux下根目录扩容

    划分出一个磁盘,并将其格式化   [root@gg ~]# mkfs.ext3 /dev/sdb2    创建一个物理卷 [root@gg ~]# pvcreate /dev/sdb2    [roo ...

  10. JSP的学习一(基础知识)

    一:介绍 1). WHY: JSP 是简 Servlet 编写的一种技术, 它将 Java 代码和 HTML 语句混合在同一个文件中编写, 只对网页中的要动态产生的内容采用 Java 代码来编写,而对 ...