题面

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. 开发工具-SSMS官方下载地址

    更新记录 2022年6月10日 完善标题. SQL Server Management Studio官方下载地址 https://docs.microsoft.com/en-us/sql/ssms/d ...

  2. 在Visual C++ 6.0中无法使用gets()函数的解决办法

    问题 昨晚遇到一个有意思的问题,明明在Visual Studio 2019运行好好的C语言代码,Copy到Visual C++ 6.0中就无法编译通过了,错误提示信息如下: error C2143: ...

  3. 百度地图API 地图圈区域并计算坐标点是否在区域内

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. php公立转农历

    <?php function nongli($riqi) { //优化修改 20160807 FXL $nian=date('Y',strtotime($riqi)); $yue=date('m ...

  5. VMware 虚拟机安装CentOS镜像详细步骤

    CentOS目前官网提供的下载版本有6.7.8,最新的版本为8,不过个人推荐CentOS 7 的版本,因为相比较于最新版本,版本7更加地稳定.而相比于版本6,版本7新增了很多的功能.CentOS 7 ...

  6. JavaWEB04-Maven&Mybatis

    今日内容 `Maven` Maven `Maven`概念&简介 Maven `Maven`安装配置 Maven `Maven`基本使用 Idea集成 `Idea`集成`Maven` Maven ...

  7. mvc 捕获404和500 等

    之前一直以为HandleErrorAttribute 可以捕获到后面自己尝试了不行,又自己想自定义页面,发现不行,然后设置了<customErrors/>节点 又不符合SEO 返回stat ...

  8. ApiDay001 __02 Java_StringBuilder

    Java 核心API StringBuilder String 类型的连接性能不好,Java提供了StringBuilder解决字符串连接性能问题. 简单理解 StringBuilder性能好!(重点 ...

  9. 3.Android高仿网易云音乐-首页复杂发现界面布局和功能/RecyclerView复杂布局

    0.效果图 效果图依次为发现界面顶部,包含首页轮播图,水平滚动的按钮,推荐歌单:然后是发现界面推荐单曲,点击单曲就是直接进入播放界面:最后是全局播放控制条上点击播放列表按钮显示的播放列表弹窗. 1.整 ...

  10. python主动杀死线程

    简介 在一些项目中,为了防止影响主进程都会在执行一些耗时动作时采取多线程的方式,但是在开启线程后往往我们会需要快速的停止某个线程的动作,因此就需要进行强杀线程,下面将介绍两种杀死线程的方式. 直接强杀 ...