[BZOJ1861][Zjoi2006]Book 书架
[BZOJ1861][Zjoi2006]Book 书架
试题描述
小T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能有X-1、X或X+1本书。 当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。 久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作,以及回答她的两个提问:(1)编号为X的书在书柜的什么位置;(2)从上到下第i本书的编号是多少。
输入
第一行有两个数n,m,分别表示书的个数以及命令的条数;第二行为n个正整数:第i个数表示初始时从上至下第i个位置放置的书的编号;第三行到m+2行,每行一条命令。命令有5种形式: 1. Top S——表示把编号为S的书放在最上面。 2. Bottom S——表示把编号为S的书放在最下面。 3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书; 4. Ask S——询问编号为S的书的上面目前有多少本书。 5. Query S——询问从上面数起的第S本书的编号。
输出
输入示例
Query
Top
Ask
Bottom
Ask
Top
Insert -
Query
Query
Ask
输出示例
数据规模及约定
100%的数据,n,m < = 80000
题解
让每个节点的编号与它在伸展树中的编号一致,查找排名时利用子树大小,查询某节点排名时把它伸展到根就好了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 80010
struct Node {
int siz;
Node() {}
} ns[maxn];
int ToT, fa[maxn], ch[2][maxn], id[maxn];
void maintain(int o) {
ns[o].siz = 1;
for(int i = 0; i < 2; i++) if(ch[i][o])
ns[o].siz += ns[ch[i][o]].siz;
return ;
}
void build(int& o, int l, int r) {
if(l > r) return ;
int mid = l + r >> 1; o = id[mid];
build(ch[0][o], l, mid - 1); build(ch[1][o], mid + 1, r);
if(ch[0][o]) fa[ch[0][o]] = o;
if(ch[1][o]) fa[ch[1][o]] = o;
return maintain(o);
}
void rotate(int u) {
int y = fa[u], z = fa[y], l = 0, r = 1;
if(z) ch[ch[1][z]==y][z] = u;
if(ch[1][y] == u) swap(l, r);
fa[u] = z; fa[y] = u; fa[ch[r][u]] = y;
ch[l][y] = ch[r][u]; ch[r][u] = y;
maintain(y); maintain(u);
return ;
}
void splay(int u) {
while(fa[u]) {
int y = fa[u], z = fa[y];
if(z) {
if(ch[0][y] == u ^ ch[0][z] == y) rotate(u);
else rotate(y);
}
rotate(u);
}
return ;
}
int splitl(int u) {
splay(u);
int tmp = ch[0][u];
fa[tmp] = ch[0][u] = 0;
maintain(u);
return tmp;
}
int splitr(int u) {
splay(u);
int tmp = ch[1][u];
fa[tmp] = ch[1][u] = 0;
maintain(u);
return tmp;
}
int merge(int a, int b) {
if(!a) return maintain(b), b;
if(!b) return maintain(a), a;
while(ch[1][a]) a = ch[1][a];
splay(a);
ch[1][a] = b; fa[b] = a;
return maintain(a), a;
}
int getrt() {
int u = 1; while(fa[u]) u = fa[u];
return u;
}
int Find(int o, int k) {
if(!o) return 0;
int ls = ch[0][o] ? ns[ch[0][o]].siz : 0;
if(k == ls + 1) return o;
if(k > ls + 1) return Find(ch[1][o], k - ls - 1);
return Find(ch[0][o], k);
} int main() {
int n = read(), q = read();
for(int i = 1; i <= n; i++) id[i] = read();
int tmp = 0; build(tmp, 1, n); int tq = q;
while(q--) {
char cmd[10]; scanf("%s", cmd);
if(cmd[0] == 'T') {
int mrt = read(), lrt = splitl(mrt), rrt = splitr(mrt);
lrt = merge(lrt, rrt); merge(mrt, lrt);
}
if(cmd[0] == 'B') {
int mrt = read(), lrt = splitl(mrt), rrt = splitr(mrt);
lrt = merge(lrt, rrt); merge(lrt, mrt);
}
if(cmd[0] == 'I') {
int mrt = read(), t = read(), rk, lrt, rrt;
if(!t) continue;
splay(mrt); rk = (ch[0][mrt] ? ns[ch[0][mrt]].siz : 0) + 1 + t;
if(rk < 1 || rk > n) continue; rk = Find(getrt(), rk);
if(t < 0) {
lrt = splitl(rk); splitl(mrt); rrt = splitr(mrt);
lrt = merge(lrt, mrt); lrt = merge(lrt, rk); merge(lrt, rrt);
}
else {
lrt = splitl(mrt); splitl(rk); rrt = splitr(rk);
lrt = merge(lrt, rk); lrt = merge(lrt, mrt); merge(lrt, rrt);
}
}
if(cmd[0] == 'A') {
int u = read();
splay(u);
printf("%d\n", ch[0][u] ? ns[ch[0][u]].siz : 0);
}
if(cmd[0] == 'Q') printf("%d\n", Find(getrt(), read()));
} return 0;
}
[BZOJ1861][Zjoi2006]Book 书架的更多相关文章
- [bzoj1861][Zjoi2006]Book 书架_非旋转Treap
Book 书架 bzoj-1861 Zjoi-2006 题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底):将指定编号元素左右篡位:查询指定编号元素位置:查询指定数量位置元素编号. ...
- fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架
题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...
- BZOJ1861[ZJOI2006]Book书架
Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下 ...
- 【平衡树】【pb_ds】 bzoj1861 [Zjoi2006]Book 书架
需要用数组记录编号为i的书的位置,和位置i处的书的编号. Code: #include<cstdio> #include<ext/pb_ds/assoc_container.hpp& ...
- 【权值分块】bzoj1861 [Zjoi2006]Book 书架
权值分块……rank3……没什么好说的. #include<cstdio> #include<cmath> #include<algorithm> using na ...
- bzoj1861 [Zjoi2006]Book 书架 splay
小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些书太有吸引 ...
- 并不对劲的bzoj1861: [Zjoi2006]Book 书架
传送门-> 这题的正确做法是splay维护这摞书. 但是并不对劲的人选择了暴力(皮这一下很开心). #include<algorithm> #include<cmath> ...
- bzoj1861 [Zjoi2006]Book 书架——splay
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1861 发现自己想splay的时候总是纠结那个点权是什么,因为splay原本是二分查找树... ...
- BZOJ 1861: [Zjoi2006]Book 书架
1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1290 Solved: 740[Submit][Stat ...
随机推荐
- go http.Get请求 http.Post请求 http.PostForm请求 Client 超时设置
http中有Get/Post/PostForm方法 也可以通过http包中设置client 请求配置 ,然后通过client.Do方法实现请求 下demo中功能都实现,其中有详细说明: package ...
- NFS简单使用
NFS网络文件系统(Network File System),由Sun公司开发,从名字上就能够知道这个服务是通过网络的方式来共享文件系统,目前RHEL 6上使用的版本为NFSv4,提供有状态的连接,追 ...
- Atomikos的使用过程中要注意的事
在使用Atomikos过程中遇到的一些问题,以作记录: MySQL does not support TMJOIN MySQL does not allow for joining an existi ...
- python读取caffemodel文件
caffemodel是二进制的protobuf文件,利用protobuf的python接口可以读取它,解析出需要的内容 不少算法都是用预训练模型在自己数据上微调,即加载"caffemodel ...
- bzoj1415[NOI2005]聪聪和可可-期望的线性性
这道题之前我写过一个巨逗比的写法(传送门:http://www.cnblogs.com/liu-runda/p/6220381.html) 当时的原因是这道题可以抽象出和"绿豆蛙的归宿&qu ...
- git 远程仓库
1.查看当前的远程库 git remote git remote -v 2.添加远程仓库 git remote add [shortname] [url] 3.从远程仓库抓取数据 git fetch ...
- Redis 3.0.5 集群的命令、使用、维护
cluster命令 CLUSTER INFO 打印集群的信息 CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息. //节点 CLUSTER MEET < ...
- 每天一个 Linux 命令(21):find命令之xargs
在使用 find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行.但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出 ...
- json基础
1 xml缺点 用xml表示一个对象,数据存储效率低 <person> <firstName>Morra<firstName> <lastName>Do ...
- SVN 提交报错:×××文件is not under version control
解决方法:1.删除出错的文件,然后在出错文件所在文件夹执行还原操作 2.VS中可将文件先排除在项目外,再包含在项目内,即可正常提交