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

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

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

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

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

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 200050
#define Key_value ch[ch[root][1]][0]
pair<int,int>question[maxn];
int tot,pos[maxn],s[maxn],e[maxn],qishi[maxn];
int t; int cnt,rt;
int pre[maxn],ch[maxn][2],sz[maxn],num[maxn]; void Treaval(int x) {
if(x) {
Treaval(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d , num= %2d \n",x,ch[x][0],ch[x][1],pre[x],sz[x],num[x]);
Treaval(ch[x][1]);
}
}
void debug() {printf("%d\n",rt);Treaval(rt);} void newnode(int &x,int father,int qujian)
{
x=qujian; //为了方便,这里树上节点的编号就是区间的编号
pre[x]=father;ch[x][0]=ch[x][1]=0;
sz[x]=num[x]=e[x]-s[x]+1;
} void pushup(int x)
{
sz[x]=sz[ch[x][0] ]+sz[ch[x][1] ]+num[x];
}
void build(int &x,int l,int r,int father)
{
if(l>r)return;
int mid=(l+r)/2;
newnode(x,father,mid); build(ch[x][0],l,mid-1,x);
build(ch[x][1],mid+1,r,x);
pushup(x);
} void init()
{
cnt=rt=0;
pre[rt]=ch[rt][0]=ch[rt][1]=sz[rt]=0;
build(rt,1,t,0);
} void rotate(int x,int p)
{
int y=pre[x];
ch[y][!p]=ch[x][p];
pre[ch[x][p] ]=y;
if(pre[y])ch[pre[y] ][ch[pre[y] ][1]==y ]=x;
pre[x]=pre[y];
ch[x][p]=y;
pre[y]=x;
pushup(y);pushup(x);
}
void splay(int x,int goal)
{
while(pre[x]!=goal){
if(pre[pre[x] ]==goal){
rotate(x,ch[pre[x]][0]==x);
}
else{
int y=pre[x];int z=pre[y];
int p=ch[pre[y] ][0]==y;
if(ch[y][p]==x )rotate(x,!p);
else rotate(y,p);
rotate(x,p);
}
}
if(goal==0)rt=x;
pushup(x);
} int get_kthjiedian(int &x,int k)
{
int t1=sz[ch[x][0] ]+1;
int t2=sz[ch[x][0] ]+num[x]; if(k>=t1 && k<=t2)return x;
if(k<t1)return get_kthjiedian(ch[x][0],k);
if(k>t2)return get_kthjiedian(ch[x][1],k-t2 );
}
int get_min(int r)
{
while(ch[r][0])
{
r = ch[r][0];
}
return r;
}
int get_kthweizhi(int r,int k)
{
int t = sz[ch[r][0]];
if(k <= t)return get_kthweizhi(ch[r][0],k);
else if(k <= t + num[r]) return s[r] + k - t - 1;
else return get_kthweizhi(ch[r][1],k - t - num[r]);
}
void del()
{
if(ch[rt][0]==0 ){
rt=ch[rt][1];
pre[rt]=0;
}
else{
int y=ch[rt][0];
int x=ch[rt][1];
while(ch[y][1]){
y=ch[y][1];
}
splay(y,rt);
ch[y][1]=x;
pre[x]=y;
rt=y;
pre[rt]=0;
pushup(rt);
}
} int bin(int x)
{
int l = 1, r = t;
while(l <= r)
{
int mid = (l+r)/2;
if(s[mid] <= x && x <= e[mid])return mid;
if(x < s[mid])r = mid-1;
else l = mid+1;
}
return -1;
} int main()
{
int n,m,i,j,T,c,d,cas=0;
char str[10];
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
tot=0;
for(i=1;i<=m;i++){
scanf("%s%d",str,&c);
if(str[0]=='T')question[i]=make_pair(1,c);
else if(str[0]=='Q')question[i]=make_pair(2,c);
else question[i]=make_pair(3,c);
pos[++tot]=c;
}
pos[++tot]=1;pos[++tot]=n;
sort(pos+1,pos+1+tot);
tot=unique(pos+1,pos+1+tot)-pos-1; s[1]=e[1]=pos[1];
t=1;
for(i=2;i<=tot;i++){
if(pos[i]-pos[i-1]>1){
t++;s[t]=pos[i-1]+1;e[t]=pos[i]-1;
}
t++;s[t]=e[t]=pos[i];
}
init();
int qujian;
printf("Case %d:\n",++cas);
for(i=1;i<=m;i++){
c=question[i].first;d=question[i].second;
if(c==1){
int r=bin(d);
splay(r,0);
del();
splay(get_min(rt),0); //这里必须直接把删除的节点放到根节点上,不然会T额。。
ch[r][0] = 0;
ch[r][1] = rt;
pre[rt] = r;
rt = r;
pre[rt] = 0;
num[rt]=e[rt]-s[rt]+1;
pushup(rt);
}
if(c==2){
qujian=bin(d);
splay(qujian,0);
printf("%d\n",sz[ch[rt][0] ]+1);
}
else if(c==3){
printf("%d\n",get_kthweizhi(rt,d));
}
}
}
return 0;
}

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 900050
#define Key_value ch[ch[root][1]][0]
pair<int,int>question[maxn];
int tot,pos[maxn],s[maxn],e[maxn],qishi[maxn];
int t;
map<int,int>mp;
map<int,int>::iterator it; int cnt,rt;
int pre[maxn],ch[maxn][2],sz[maxn],num[maxn]; void Treaval(int x) {
if(x) {
Treaval(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d , num= %2d \n",x,ch[x][0],ch[x][1],pre[x],sz[x],num[x]);
Treaval(ch[x][1]);
}
}
void debug() {printf("%d\n",rt);Treaval(rt);} void newnode(int &x,int father)
{
x=++cnt;
pre[x]=father;ch[x][0]=ch[x][1]=0;
} void pushup(int x)
{
sz[x]=sz[ch[x][0] ]+sz[ch[x][1] ]+num[x];
}
void build(int &x,int l,int r,int father)
{
if(l>r)return;
int mid=(l+r)/2;
newnode(x,father);
sz[cnt]=num[cnt]=e[mid]-s[mid]+1;
qishi[cnt]=s[mid];
if(num[cnt]==1)mp[s[mid]]=cnt; build(ch[x][0],l,mid-1,x);
build(ch[x][1],mid+1,r,x);
pushup(x);
} void init()
{
cnt=rt=0;
pre[rt]=ch[rt][0]=ch[rt][1]=sz[rt]=0;
build(rt,1,t,0);
} void rotate(int x,int p)
{
int y=pre[x];
ch[y][!p]=ch[x][p];
pre[ch[x][p] ]=y;
if(pre[y])ch[pre[y] ][ch[pre[y] ][1]==y ]=x;
pre[x]=pre[y];
ch[x][p]=y;
pre[y]=x;
pushup(y);pushup(x);
}
void splay(int x,int goal)
{
while(pre[x]!=goal){
if(pre[pre[x] ]==goal){
rotate(x,ch[pre[x]][0]==x);
}
else{
int y=pre[x];int z=pre[y];
int p=ch[pre[y] ][0]==y;
if(ch[y][p]==x )rotate(x,!p);
else rotate(y,p);
rotate(x,p);
}
}
if(goal==0)rt=x;
pushup(x);
} int get_kthjiedian(int &x,int k)
{
int t1=sz[ch[x][0] ]+1;
int t2=sz[ch[x][0] ]+num[x]; if(k>=t1 && k<=t2)return x;
if(k<t1)return get_kthjiedian(ch[x][0],k);
if(k>t2)return get_kthjiedian(ch[x][1],k-t2 );
} int get_kthweizhi(int &x,int k)
{
int t1=sz[ch[x][0] ]+1;
int t2=sz[ch[x][0] ]+num[x];
if(k>=t1 && k<=t2){
int ans=qishi[x]+k-t1;
splay(x,0);
return ans;
}
else if(k<t1)return get_kthweizhi(ch[x][0],k);
else return get_kthweizhi(ch[x][1],k-t2 ); } void del()
{
if(ch[rt][0]==0 ){
rt=ch[rt][1];
pre[rt]=0;
}
else{
int y=ch[rt][0];
int x=ch[rt][1];
while(ch[y][1]){
y=ch[y][1];
}
splay(y,rt);
ch[y][1]=x;
pre[x]=y;
rt=y;
pre[rt]=0;
pushup(rt);
}
} int get_min(int x)
{
int r=x;
while(ch[r][0]){
r=ch[r][0];
}
return r;
} int main()
{
int n,m,i,j,T,c,d,cas=0;
char str[10];
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
tot=0;
for(i=1;i<=m;i++){
scanf("%s%d",str,&c);
if(str[0]=='T')question[i]=make_pair(1,c);
else if(str[0]=='Q')question[i]=make_pair(2,c);
else question[i]=make_pair(3,c);
pos[++tot]=c;
}
pos[++tot]=1;pos[++tot]=n;
sort(pos+1,pos+1+tot);
tot=unique(pos+1,pos+1+tot)-pos-1; s[1]=e[1]=pos[1];
t=1;
for(i=2;i<=tot;i++){
if(pos[i]-pos[i-1]>1){
t++;s[t]=pos[i-1]+1;e[t]=pos[i]-1;
}
t++;s[t]=e[t]=pos[i];
}
init();
printf("Case %d:\n",++cas);
for(i=1;i<=m;i++){
c=question[i].first;d=question[i].second;
if(c==1){
int geshu=num[mp[d] ];
int kaishi=qishi[mp[d] ];
splay(mp[d],0);
del();
splay(get_min(rt),0 );
cnt++;
qishi[cnt]=kaishi;
pre[cnt]=0;num[cnt]=geshu;
pre[rt]=cnt;
ch[cnt][0]=0;ch[cnt][1]=rt;
rt=cnt;
mp[d]=cnt;
pushup(rt);
}
if(c==2){
splay(mp[d],0);
printf("%d\n",sz[ch[rt][0] ]+1);
}
else if(c==3){
printf("%d\n",get_kthweizhi(rt,d));
}
}
}
return 0;
}

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. Java安全之Weblogic 2016-3510 分析

    Java安全之Weblogic 2016-3510 分析 首发安全客:Java安全之Weblogic 2016-3510 分析 0x00 前言 续前面两篇文章的T3漏洞分析文章,继续来分析CVE-20 ...

  2. 服务器报错"您的主机中的软件中止了一个已建立的连接"

    网上很多的说法都模棱两可,只是说和远程连接有关,这个说的太泛泛了. 我现在遇到的问题是java web出现的, 执行表单提交的时候出现该错误,原因是ajax和表单同时提交导致的, 相信很多朋友用了aj ...

  3. Kubernetes K8S之kube-prometheus概述与部署

    Kubernetes K8S之kube-prometheus概述与部署 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7. ...

  4. [Usaco2002 Feb]Rebuilding Roads重建道路

    题目描述 一场可怕的地震后,奶牛用N个牲口棚(1 <= N <= 150,编号1..N)重建了农民John的牧场.奶牛没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是唯一 ...

  5. Sgu149 Computer Network

    Sgu149 Computer Network 题目描述 给你一棵N(N<=10000)个节点的树,求每个点到其他点的最大距离. 不难想到一个节点到其他点的最大距离为:max(以它为根的子树的最 ...

  6. Qt Undo Framework

    Qt undo/redo 框架 基于Command设计模式 支持命令压缩和命令合成 提供了与工具包其他部分融合很好的widgets和actions 术语(Terminology) Command - ...

  7. 【故障公告】K8s CofigMap 挂载问题引发网站故障

    今天凌晨我们用阿里云服务器自建的 kubernetes 集群出现突发异常情况,博客站点(blog-web)与博客 web api(blog-api)的 pod 无法正常启动(CrashLoopBack ...

  8. idea maven package报错"不再支持源选项 5 请使用 6 或更高版本。不支持发行版本 5"

    解决办法: 1.确保java compile以及project和module的java字节码版本是所用的java版本:

  9. https://tools.ietf.org/html/rfc8017

    PKCS #1: RSA Cryptography Specifications Version 2.2

  10. WPF排版布局经验总结(干货)简短不疲倦

    本文不过多讲述wpf的基础布局控件,本文只记录WPF排版的技巧,这是个人的总结,不能符合所有情况,如果有何不对的地方,请评论指正,谢谢. 1.区域划分 在接手一个界面的时候,先纵观全局,将眼见的区域划 ...