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.
 
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
 
/*
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;
}

  

hdu 3436 splay树+离散化*的更多相关文章

  1. hdu 3436 线段树 一顿操作

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

  2. hdu 1890 splay树

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

  3. ZOJ 2301/HDU 1199 线段树+离散化

    给这个题目跪了两天了,想吐简直 发现自己离散化没学好 包括前一个离散化的题目,实际上是错了,我看了sha崽的博客后才知道,POJ那题简直数据弱爆了,本来随便一组就能让我WA掉的,原因在于离散化的时候, ...

  4. hdu 5792 线段树+离散化+思维

    题目大意: Given a sequence A with length n,count how many quadruple (a,b,c,d) satisfies: a≠b≠c≠d,1≤a< ...

  5. HDU 1542 线段树离散化+扫描线 平面面积计算

    也是很久之前的题目,一直没做 做完之后觉得基本的离散化和扫描线还是不难的,由于本题要离散x点的坐标,最后要计算被覆盖的x轴上的长度,所以不能用普通的建树法,建树建到r-l==1的时候就停止,表示某段而 ...

  6. HDU 4288 线段树+离散化

    题意: n个操作 在[1, 100000]  的区间上add 或del数( 必不会重复添加或删除不存在的数) sum 求出整个集合中 (下标%5 == 3 位置) 的数   的和 注意数据类型要64位 ...

  7. HDU 5862 Counting Intersections(离散化+树状数组)

    HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...

  8. Splay树学习

    首先给出一论文讲的很好: http://www.docin.com/p-63165342.html http://www.docin.com/p-62465596.html 然后给出模板胡浩大神的模板 ...

  9. 1439. Battle with You-Know-Who(splay树)

    1439 路漫漫其修远兮~ 手抄一枚splay树 长长的模版.. 关于spaly树的讲解   网上很多随手贴一篇 貌似这题可以用什么bst啦 堆啦 平衡树啦 等等 这些本质都是有共同点的 查找.删除特 ...

随机推荐

  1. codevs 1291 火车线路

    http://codevs.cn/problem/1291/ 题目描述 Description 某列火车行使在C个城市之间(出发的城市编号为1,结束达到的城市的编号为C),假设该列火车有S个座位,现在 ...

  2. UDP协议实现客户服务器数据交互

    UDP协议实现客户服务器数据交互 按照往常一样将今天自己写的题目答案写在了博客上习题:客户端循环发送消息给服务端,服务端循环接收,并打印出来,直到收到Bye就退出程序. package network ...

  3. linux下xargs和管道的区别

    管道将前面的标准输出作为后面的标准输入,xargs则将标准输入作为命令的参数 一.简介 1.背景 之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了x ...

  4. GIT入门笔记(7)- 修改文件并向版本库提交

    1.修改文件vi readme.txt git status 发现被修改的文件列表git diff readme.txt 2.git add readme.txt git status  --注意gi ...

  5. Docker学习笔记 - Docker的远程访问

    学习内容: 配置客户端与守护进程的远程访问 服务端配置-H选项: 使服务端支持远程被访问 客户端使用-H选项: 使客户端访问远程服务端 本地环境DOCKER_HOST设置客户端访问的默认服务端地址 准 ...

  6. 新概念英语(1-39)Don't drop it!

    新概念英语(1-39)Don't drop it! Where does Sam put the vase in the end ? A:What are you going to do with t ...

  7. SpringCloud的EurekaClient : 客户端应用访问注册的微服务(无断路器场景)

    演示客户端应用如何访问注册在EurekaServer里的微服务 一.概念和定义 采用Ribbon或Feign方式访问注册到EurekaServer中的微服务.1.Ribbon实现了客户端负载均衡,2. ...

  8. Python之面向对象三

    面向对象的三大特性: 多态 多态指的是一类事物有多种形态.Python3天生支持多态. 动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.ABCM ...

  9. Linux中的重启命令

    1.系统重启: shutdowm    该命令安全地将系统关机. 有些用户会使用直接断掉电源的方式来关闭linux,这是十分危险的.因为linux与windows不同,其后台运行着许多进程,所以强制关 ...

  10. this对象指向

    this表示函数运行时,自动生成的一个内部对象,只能在函数内部运行 function test(){ this.x = 1; } 随着使用场景的变化,this的值会发生变化 原则:this指的值调用函 ...