题面

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.

题解

这道题标签是平衡树,所以要用平衡树做。

这道题的N很大,但Q很小,但是又有数字又有序号导致我们不好用离散化。

回想一下线段树,当我们想用离散又不能用的时候,我们就会用动态开点。

这道题也是一个道理,我们一开始用一个大点存1~N,以后每个小点都存一个子区间,

再用另一棵树存出现过的数字,每次找前缀,再通过这个前缀找到包含它的子区间的第一棵树上的节点编号。

CODE

本人代码有点丑,请见谅。

(别复制了,我特地把一个地方改成错的了)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define LL long long
#define MAXN 200000 + 5
using namespace std;
inline LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
return x * f;
}
LL n,m,i,j,s,o,k,cnt,root,root2;
struct tr{
int s[2];
LL key;
int heap,siz,cntp,nml,nmr;
tr(){key = 0;s[0] = s[1] = 0;heap = 0;siz = 0;cntp = 0;nml = 0;nmr = 0;}
}tre[MAXN];
int maketre(LL ky,int hp,int numl,int numr) {
tre[++cnt] = tr();
tre[cnt].key = ky;
tre[cnt].heap = hp;
tre[cnt].s[0] = tre[cnt].s[1] = 0;
tre[cnt].siz = tre[cnt].cntp = numr - numl + 1;
tre[cnt].nml = numl;
tre[cnt].nmr = numr;
return cnt;
}
void update(int x) {
tre[x].siz = tre[tre[x].s[0]].siz + tre[tre[x].s[1]].siz + tre[x].cntp;
return ;
}
int splay(int x,int d) {
int ad = tre[x].s[d];
tre[x].s[d] = tre[ad].s[d^1];
tre[ad].s[d^1] = x;
update(x);
update(ad);
return ad;
}
int ins(int x,LL tk,int numl,int numr) {
if(x == 0) return maketre(tk,unsigned(rand()) + 1,numl,numr);
if(tre[x].key == tk) {
tre[x].cntp ++;
update(x);
return x;
}
int d = tk > tre[x].key;
tre[x].s[d] = ins(tre[x].s[d],tk,numl,numr);
if(tre[tre[x].s[d]].heap < tre[x].heap) return splay(x,d);
update(x);
return x;
}
int del(int x,LL ky) {
if(x == 0) return 0;
if(tre[x].key == ky) {
if(tre[x].cntp > 1) {
tre[x].cntp --;
update(x);
return x;
}
else {
if(tre[x].s[0] && tre[x].s[1]) {
int d = tre[tre[x].s[1]].heap < tre[tre[x].s[0]].heap;
int rep = splay(x,d);
tre[rep].s[d^1] = del(x,ky);
update(rep);
return rep;
}
if(tre[x].s[0]) return tre[x].s[0];
return tre[x].s[1];
}
}
else {
int d = ky > tre[x].key;
tre[x].s[d] = del(tre[x].s[d],ky);
update(x);
return x;
}
}
int idp(int x,LL m) {
if(x == 0) return 0;
if(tre[tre[x].s[0]].siz < m && tre[tre[x].s[0]].siz + tre[x].cntp >= m) {
return x;
}
if(tre[tre[x].s[0]].siz >= m) {
return idp(tre[x].s[0],m);
}
return idp(tre[x].s[1],m - tre[tre[x].s[0]].siz - tre[x].cntp);
}
int pa(int x,LL m) {
int ren;
if(x == 0) ren = 1;
else if(tre[x].key == m) {
ren = tre[tre[x].s[0]].siz + 1;
}
else if(tre[x].key > m) {
ren = pa(tre[x].s[0],m);
}
else ren = pa(tre[x].s[1],m) + tre[tre[x].s[0]].siz + tre[x].cntp;
return ren;
}
int pre(int root,LL m) {
int rep = pa(root,m);
return idp(root,rep - 1);
}
int nex(int root,LL m) {
int rep = pa(root,m);
int repd = idp(root,rep);
if(tre[repd].key == m) return idp(root,rep + tre[repd].cntp);
return idp(root,rep);
}
int main() {
int T = read(),cn = 0;
while(T --) {
printf("Case %d:\n",++cn);
cnt = root = root2 = 0;
n = read();m = read();
root = ins(root,1,1,n);
root2 = ins(root2,1,cnt,cnt);
char ss[20];
for(int i = 1;i <= m;i ++) {
scanf("%s",ss + 1);s = read();
if(ss[1] == 'T') {
int d = pre(root2,s + 1);
d = tre[d].nml;
int l = tre[d].nml,r = tre[d].nmr,ky = tre[d].key;
root = del(root,ky);
root2 = del(root2,l);
if(l < s) {
root = ins(root,ky,l,s - 1);
root2 = ins(root2,l,cnt,cnt);
}
if(r > s) {
root = ins(root,ky + (s+1 - l),s + 1,r);
root2 = ins(root2,s + 1,cnt,cnt);
}
d = idp(root,1);
root = ins(root,tre[d].key - 1,s,s);
root2 = ins(root2,s,cnt,cnt);
}
else if(ss[1] == 'Q') {
int d = pre(root2,s + 1);
d = tre[d].nml;
int l = tre[d].nml,r = tre[d].nmr,ky = tre[d].key;
printf("%d\n",pa(root,ky) + s - l);
}
else if(ss[1] == 'R') {
int d = idp(root,s);
int p = pa(root,tre[d].key);
printf("%d\n",tre[d].nml + s - p);
}
}
}
return 0;
}

Queue-jumpers - 平衡树的更多相关文章

  1. [BZOJ3224]Tyvj 1728 普通平衡树

    [BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...

  2. [知识点]平衡树之Splay

    // 此博文为迁移而来,写于2015年7月18日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6rg.html 1.前 ...

  3. K-集合 (JXNU第二次周赛1006)set/平衡树

    K-集合 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submissi ...

  4. 【BZOJ】3223: Tyvj 1729 文艺平衡树(splay)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3223 默默的.. #include <cstdio> #include <cstr ...

  5. 三大平衡树(Treap + Splay + SBT)总结+模板[转]

    Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...

  6. BZOJ 3224: Tyvj 1728 普通平衡树 vector

    3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...

  7. CF 19D - Points 线段树套平衡树

    题目在这: 给出三种操作: 1.增加点(x,y) 2.删除点(x,y) 3.询问在点(x,y)右上方的点,如果有相同,输出最左边的,如果还有相同,输出最低的那个点 分析: 线段树套平衡树. 我们先离散 ...

  8. tyvj 普通平衡树 SBT or splay

    普通平衡树 From admin     背景 Background 此为平衡树系列第一道:普通平衡树     描述 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中 ...

  9. 【BZOJ1146】【树链剖分+平衡树】网络管理Network

    Description M 公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通 信网络.该网络的结构由N个 ...

  10. hiho一下103周 平衡树·Treap

    平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二 ...

随机推荐

  1. swap函数模板

    在许多应用程序中,都有交换相同类型的两个变量内容的需要.例如,在对整数数组进行排序时,将需要一个函数来交换两个变量的值,如下所示: void swap(int &a, int &b) ...

  2. FFT 小记

    写在前面 \(Q:\) 为什么会心血来潮去学 FFT \(A:\) 当本蒟蒻还在努力消化凸包时:.所以本蒟蒻也来看一下 等等 摸头警告 .思维已经废了 About FFT FFT( \(Fast\ F ...

  3. 使用PowerShell压缩和解压ZIP包

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月13日. 解压ZIP包 使用PowerShell的Expand-Archive命令.PowerShell官方文档地址. 命令格式: ...

  4. 6大优势、2种类型,一文吃透动态应用安全测试(DAST)

    在在上篇文章中中,我们了解了 SAST 的概念.优劣和使用的工具,并在文章里提到了另一个软件安全领域里的重要技术 DAST.本文将会详细介绍 DAST 的概念.重要性及其工作原理.   DAST(Dy ...

  5. 合宙AIR105(二): 时钟设置和延迟函数

    目录 合宙AIR105(一): Keil MDK开发环境, DAP-Link 烧录和调试 合宙AIR105(二): 时钟设置和延迟函数 Air105 的时钟 高频振荡源 芯片支持使用内部振荡源, 或使 ...

  6. 名校AI课推荐 | UC Berkeley《人工智能导论》

    深度学习具备强感知能力但缺乏一定的决策能力,强化学习具备决策能力但对感知问题束手无策,因此将两者结合起来可以达到优势互补的效果,为复杂系统的感知决策问题提供了解决思路. 今天我们推荐这样一门课程--U ...

  7. 【Java面试】@Resource 和 @Autowired 的区别

    Hi,大家好,我是Mic. 一个工作2年的粉丝,问我一个Spring里面的问题. 希望我能从不同的视角去分析,然后碾压面试官. 这个问题是: "@Resource和@Autowired&qu ...

  8. 循环结构-for循环和while循环

    循环语句1--for for循环语句格式: for(初始化表达式①; 布尔表达式②; 步进表达式④){ 循环体③ } 执行流程 执行顺序:①②③④>②③④>②③④-②不满足为止. ①负责完 ...

  9. .NET(C#)发送邮件的实现方法

    .NET(C#)发送邮件的实现方法 微软已经为我们准备好了现成的工具类供我们调用: MailMessage //邮件信息类 SmtpClient //邮件发送类 首先需要在项目的类文件中引用以下命名空 ...

  10. .net webapi 实现 接口版本控制并打通swagger支持

    我们在开发 webapi 项目时如果遇到 api 接口需要同时支持多个版本的时候,比如接口修改了入参之后但是又希望支持老版本的前端(这里的前端可能是网页,可能是app,小程序 等等)进行调用,这种情况 ...