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 ...
随机推荐
- scala tuple中的syntactic sugar
List[Tuple2[String, Int]] // Base List[(String, Int)] // Syntactic sugar List[Tuple3[String, Float, ...
- 【小程序开发】上拉加载更多demo
wxml: <scroll-view class='swiper-scroll' scroll-y="{{true}}" bindscrolltolower="lo ...
- python网络编程-Select\Poll\Epoll异步IO
首先列一下,sellect.poll.epoll三者的区别 select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select ...
- ls和cd命令详解
ls命令 命令功能: 列出当前目录下或者指定目录下的所有文件和目录,ls是list的缩写. 命令语法: ls [选项][目录名 ] #注:[ ]中的内容为非必选项 命令选项: | 选项 | 含义 ...
- UFLDL 教程学习笔记(三)
教程地址:http://ufldl.stanford.edu/tutorial/supervised/SoftmaxRegression/ logstic regression是二分类的问题,如果想要 ...
- thinkphp模型创建
- 浮动元素垂直居中,bootstrap栅格布局垂直居中
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【转】Python验证码识别处理实例
原文出处: 林炳文(@林炳文Evankaka) 一.准备工作与代码实例 1.PIL.pytesser.tesseract (1)安装PIL:下载地址:http://www.pythonware.com ...
- gtk+学习笔记(八)
框架(Frames)可以用于在盒子中封装一个或一组构件,框架本身还可以有一个标签.标签的位置和盒子的风格可以灵活改变. 框架可以用下面的函数创建: GtkWidget *gtk_frame_new( ...
- 20165333 学习基础和C语言学习基础
说实话,我并没有什么技能比90%以上的人更好,非要拿一个出来的话,篮球勉强好一点吧.最初接触篮球是小学的时候跟着哥哥看他打球,哥哥的球技在同龄人中算是好的,每次看他各种突破过人,我都觉得特别潇洒帅气, ...