Queue-jumpers - 平衡树
题面
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 - 平衡树的更多相关文章
- [BZOJ3224]Tyvj 1728 普通平衡树
[BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...
- [知识点]平衡树之Splay
// 此博文为迁移而来,写于2015年7月18日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6rg.html 1.前 ...
- K-集合 (JXNU第二次周赛1006)set/平衡树
K-集合 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submissi ...
- 【BZOJ】3223: Tyvj 1729 文艺平衡树(splay)
http://www.lydsy.com/JudgeOnline/problem.php?id=3223 默默的.. #include <cstdio> #include <cstr ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- BZOJ 3224: Tyvj 1728 普通平衡树 vector
3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...
- CF 19D - Points 线段树套平衡树
题目在这: 给出三种操作: 1.增加点(x,y) 2.删除点(x,y) 3.询问在点(x,y)右上方的点,如果有相同,输出最左边的,如果还有相同,输出最低的那个点 分析: 线段树套平衡树. 我们先离散 ...
- tyvj 普通平衡树 SBT or splay
普通平衡树 From admin 背景 Background 此为平衡树系列第一道:普通平衡树 描述 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中 ...
- 【BZOJ1146】【树链剖分+平衡树】网络管理Network
Description M 公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通 信网络.该网络的结构由N个 ...
- hiho一下103周 平衡树·Treap
平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二 ...
随机推荐
- 第6章 字符串(下)——C++字符串
6.5 C++ strings(C++字符串) C风格字符串常见错误:试图去访问数组范围以外的元素:没有使用函数strcpy( )来实现字符串之间的复制:没有使用函数strcmp( )来比较两个字符串 ...
- 开发工具-RSA加解密
更新日志 2022年6月10日 初始化链接. https://toolb.cn/rsa
- Weakmap详解
先看一个例子 let obj = { name: 'toto' } // { name: 'toto' }这个对象能够被读取到,因为obj这个变量名有对它的引用 // 将引用覆盖掉 obj = nul ...
- ShardingSphere-proxy-5.0.0容量范围分片的实现(五)
一.修改配置文件config-sharding.yaml,并重启服务 # # Licensed to the Apache Software Foundation (ASF) under one or ...
- bat-使用bat安装jdk和配置环境变量
文件路径 @echo off Setlocal enabledelayedexpansion @REM vscode中自动开启延迟环境变量扩展, %~d0 cd %~dp0 @REM dir echo ...
- 【万字长文】从零配置一个vue组件库
简介 本文会从零开始配置一个monorepo类型的组件库,包括规范化配置.打包配置.组件库文档配置及开发一些提升效率的脚本等,monorepo 不熟悉的话这里一句话介绍一下,就是在一个git仓库里包含 ...
- 给你准备好了——50道Python面试题集锦(附答案)
Python是目前编程领域最受欢迎的语言.在本文中,我将总结Python面试中最常见的50个问题.每道题都提供参考答案,希望能够帮助你在2019年求职面试中脱颖而出,找到一份高薪工作.这些面试题涉及P ...
- Java方法的重写
package Demo.oop.APP.Demo04; //启动器 public class application { public static void main(String[] args) ...
- NGINX屏蔽垃圾爬虫
if ($http_user_agent ~* (80legs.com|Abonti|AcoonBot|Acunetix|adbeat_bot|AddThis.com|adidxbot|ADmantX ...
- 01-vscode自定义配色方案 插件基础上
01-下载相关主题插件 02- 点击设置按钮 复制id 03-进入插件文件 C:\Users\Administrator\.vscode\extensions 04-复制刚才的id 05-themes ...