HDU 3436 Queue-jumpers (splay tree)
Queue-jumpers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1821 Accepted Submission(s): 425
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.
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.
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
3
5
8
Case 2:
Case 3:
3
6
离散化,
把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)的更多相关文章
- HDU 1890 Robotic Sort (splay tree)
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 伸展树(Splay Tree)进阶 - 从原理到实现
目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...
- 数据结构(二) --- 伸展树(Splay Tree)
文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...
- 纸上谈兵:伸展树(splay tree)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...
- 平衡树之伸展树(Splay Tree)题目整理
目录 前言 练习1 BZOJ 3224 普通平衡树 练习2 BZOJ 3223 文艺平衡树 练习3 BZOJ 1588 [HNOI2002]营业额统计 练习4 BZOJ 1208 [HNOI2004] ...
- 伸展树(splay tree)
伸展树的设计思路,鉴于数据访问的局部性(28原则)在实际应用中普遍存在,将按照"最常用者优先"的启发策略.尽管在最坏情况下其单次操作需要 O(n) 时间,但分摊而言仍然 O(log ...
- HDU 4441 Queue Sequence(splay)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:一个数列,三种操作:(1)插入:找到没在当前数列中的最小的正整数i,将其插在位置p之后,并 ...
- HDU 1890--Robotic Sort(Splay Tree)
题意:每次找出第i大的数的位置p输出,然后将i~p之间的数反转. 题解:每次把要的区间转成一棵子树,然后更新.因为每次将第i小的数转到了了i,所以k次操作后,可知前k个数一定是最小的那k个数,所以以后 ...
- BZOJ 1269: [AHOI2006]文本编辑器editor (splay tree)
1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1213 Solved: 454[Submit ...
随机推荐
- Scrapy命令行工具简介
Windows 10家庭中文版,Python 3.6.4,virtualenv 16.0.0,Scrapy 1.5.0, 在最初使用Scrapy时,使用编辑器或IDE手动编写模块来创建爬虫(Spide ...
- 【前端开发】限制input输入保留两位小数
<input type="text" name='amount' id="cash_num" placeholder="请输入金额" ...
- 移动web特殊样式处理
一.高清图片 二.一像素边框 还有一种解决办法: border-1px($color) position: relative &:after display: block position: ...
- java基础39 增强for循环(也叫foreach循环)
增强for循环是jdk1.5出现的新功能 1.增强for循环的作用 简化了迭代器的书写格式(注意:增强for循环底层还是使用了迭代器遍历) 2.增强for循环的格式 for(数据类型 变量名:遍历的目 ...
- 基于gRpc的远程服务框架
作为一个新搭建的软件团队,底层技术尤为重要.为了以后更好的面向不同的项目需求,满足不断变化的需求,决定着手搭建一套RPC系统.为了更好的兼容以后部门其他语言的使用,选择了开源框架gRpc. gRpc ...
- Unix IPC之FIFO
#include "unpipc.h" #define FIFO1 "/tmp/fifo.1" #define FIFO2 "/tmp/fifo.2& ...
- MySQL 存储过程入门
存储过程是带有逻辑的SQL语句,优点是执行效率高.缺点是可移植性差 1.存储过程语法 DELIMITER $ --声明结束符 CREATE PROCEDURE pro_test() --创建存储过程 ...
- c语言循环链表的问题
今天,老师说了一道题,大意是,有一群小朋友10个人,但是老师只有一个苹果,只能给一个小朋友,于是老师就决定让小朋友们做成一圈,从第一个小朋友开始,每隔一个小朋友就没有机会得到苹果,最后剩下的一个人可以 ...
- node模拟socket
什么是Socket?网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket通信流程 基于net模块实现socket 服务端SocketServer.j ...
- hmm学习笔记(二)
学习hmm近一周的时间,做个总结. 参考 李航的<统计学习方法>第9章,第10章 本文包含: 1.hmm模型 2.前向后向算法 3.Baum-Welch算法 4.维特比算法 1.hmm模 ...