题面

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. 验证cuda和cudnn是否安装成功(转载)

    本人cuda安装目录: 当然cuda安装目录也可默认:此处为方便安装不同cuda版本,所以单独建了文件夹. 转载自:https://zhuanlan.zhihu.com/p/139668028 安装完 ...

  2. vue项目经常遇到的Error: Loading chunk * failed

    vue项目随着代码量.业务组件.路由页面等的丰富,出于性能要求考虑不得不使用代码分割技术实现路由和组件的懒加载,这看似没什么问题 当每次通过npm run build构建生产包并部署到服务器后,操作页 ...

  3. React项目中使用less/scss&全局样式/变量

    使用create-react-app脚手架搭建初始化项目 > npm install -g create-react-app > npx create-react-app my-app c ...

  4. SAP OOALV- 合计

    TYPES: BEGIN OF ty_mara, srno LIKE adrc-name1, " Storing the total text matnr LIKE mara-matnr, ...

  5. java反射之-Javabean与Map的互转

    1.BeanUntils工具类的准备 /** * @ClassName: BeanUtils * @Description: * @Author: songwp * @Date: 9:02 2022/ ...

  6. IDEA快速创建maven项目

    遇到问题不要急,不要怕. 一.  二. 三.  四.Finish进来之后,项目会加载一会,之后会是下面这样子.  五.继续往下面配置,建立java和resorces文件夹  六.下面配置tomcat服 ...

  7. Unsupported major.minor version 52.0 (unable to load class org.apache.kafka.clients.producer.Produce异常解决方法

    在控制台输入java -version,查看自己的版本是多少,我的查出来是1.8的.随后将服务器上的改为1.8的就可以了.

  8. CentOS6安装使用ntp同步时间

    [root@server yum.repos.d]# yum install ntp已加载插件:fastestmirror, priorities, refresh-packagekit, secur ...

  9. C++ delete后的指针在不同编译器下的状态差异

    今天看到小伙伴分享的一个问题,小伙伴用的MSVC2019编译器,在对delete后的指针进行取值操作时触发了访问冲突. #include<iostream> using namespace ...

  10. Drone-比Jenkins更轻量化的持续集成部署工具

    Drone 简介 Drone 是一个基于Docker容器技术的可扩展的持续集成引擎,由GO语言编写,可用于自动化测试与构建,甚至发布.每个构建都在一个临时的Docker容器中执行,使开发人员能够完全控 ...