题面

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. 整数分解、for循环阶乘

    整数分解 整数分解是什么呢??我们可以这样理解 我们写一个 3位数求出它的个位十位和百位 . 那么我们来写一个小的测试来看一下! public static void main(String[] ar ...

  2. 菜鸟学git的基本命令及常见错误

    Git init //在当前项目工程下履行这个号令相当于把当前项目git化,变身!\ git config --global user.name "xxx" # 配置用户名 git ...

  3. Linux文件的通配符

    通配符的作用:匹配文件名 常见的通配符: *:表示任意个字符(不包括隐藏文件) ?:单个任意字符(中文也算一个字符) []:表示匹配一范围或者其中一个 表示匹配范围: [a-z] --- 不但包括了小 ...

  4. windows系统下.NET CORE c# 通过bat脚本发布iis应用程序,半智能点击式ci/cd

    这里以git为例子讲解: 第一个 pullCode.bat 文件是 拉取代码 git pull 第二个 publish.bat 脚本,编译代码,并发布指定文件夹 dotnet publish &quo ...

  5. NC13328 倒水

    NC13328 倒水 题目 题目描述 有一个大水缸,里面水的温度为 \(T\) 单位,体积为 \(C\) 升.另有 \(n\) 杯水(假设每个杯子的容量是无限的),每杯水的温度为 \(t[i]\) 单 ...

  6. Codeforces Round #789 (Div. 2) A-C

    Codeforces Round #789 (Div. 2) A-C A 题目 https://codeforces.com/problemset/problem/1677/A 题解 思路 知识点:模 ...

  7. Docker — 从入门到实践PDF下载(可复制版)

    0.9-rc2(2017-12-09)修订说明:本书内容将基于DockerCEv17.MM进行重新修订,计划2017年底发布0.9.0版本.旧版本(Docker1.13-)内容,请阅读docker-l ...

  8. 【填坑】树莓派4B上运行Bullseye版本系统,不能登录xrdp的问题~~

    以前使用 buster,安装xrdp后 pi用户xrdp登录正常, 可自从使用了 bullseye系统,pi登录xrdp后,出现黑屏不能登录现象. 网上搜寻解决方案,一种方法是: 登录树莓派后,打开这 ...

  9. day02-2

    JAVA入门 1.C&&C++ 1972年C诞生 贴近硬件,运行极快,效率极高 操作系统,编译器,数据库,网络系统等 指针和内存管理 1982年C++诞生 面向对象 兼容C 图形领域. ...

  10. 算法竞赛进阶指南 0x52 背包

    背包问题是线性背包中的一类重要问题. 0/1背包 模型: 给定N个物品,每一个物品具有两种属性,一个是体积 \(v_i\) ,另一个是容积 \(w_i\) . 有一个容积为M的背包,求一种方案,使得选 ...