题面见https://www.luogu.org/problemnew/show/P2596

题面就是描述了一个书柜从上到下放着书,可以看作一个序列,每个数的序号为它在从上向下数第几本

一开始建树偷了个懒,就直接一个个insert

因为题目中都是以书的编号进行操作,所以记一个pos[ ]

操作一:把pos[x] splay到根,左儿子都是比它编号小的,那么就把左儿子挂到根的后面,根+1的前面,具体怎么找这个点看代码解释

操作二:同一理

操作三:实际上只更改了x和x的前驱或后继的值,和他们代表的值的位置,只修改这两个标记即可

操作四:把pos[x] splay到根,左儿子都是比它编号小的,那么答案就是st[ls].size

操作五:常规查询第k大

#include<bits/stdc++.h>
using namespace std;
inline int read(){
int w=,f=;
char ch=getchar();
while(ch<''||ch>''){
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<=''){
w=(w<<)+(w<<)+ch-;
ch=getchar();
}
return w*f;
}
int n,m,cnt,tot,root,a[],pos[];
bool debug;
struct node{
int val,ch[],size,f;
}st[];
inline void push_up(int x){
int ls=st[x].ch[];int rs=st[x].ch[];
st[x].size=st[ls].size+st[rs].size+;
pos[st[ls].val]=ls;pos[st[rs].val]=rs;
}
inline bool identify(int p){
return st[st[p].f].ch[]==p;
}
inline void connect(int x,int fa,int son){
st[x].f=fa;st[fa].ch[son]=x;return;
}
inline void rotate(int x){
int y=st[x].f;int z=st[y].f;
int yson=identify(x);int zson=identify(y);
int b=st[x].ch[yson^];
connect(b,y,yson);connect(y,x,(yson^));connect(x,z,zson);
push_up(y);push_up(x);if(z)push_up(z);return;
}
inline void splay(int x,int goal){
while(st[x].f!=goal){
int y=st[x].f;int z=st[y].f;
int yson=identify(x);int zson=identify(y);
if(z!=goal){
if(yson==zson) rotate(y);
else rotate(x);
}
rotate(x);
}
if(!goal) root=x;
return;
}//这以上都是常规操作
inline void insert(int x){
cnt++;int now=cnt;st[now].size=;
st[now].val=x;pos[x]=now;st[now].ch[]=st[now].ch[]=;
if(cnt>){//只要当前节点不是根,都要将它和父亲连一下,并splay到根
st[now].f=now-;st[now-].ch[]=now;
splay(now,);
}
}//建树操作 inline void output(int x){
int ls=st[x].ch[];int rs=st[x].ch[];
if(ls) output(ls);
printf("%d ",st[x].val);
if(rs) output(rs);
return;
}//输出整颗区间树,debug用的 inline int find(int p,int rk){
int ls=st[p].ch[];int rs=st[p].ch[];
if(st[ls].size+==rk) return p;
if(st[ls].size>=rk) return find(ls,rk);
return find(rs,rk-st[ls].size-);
}//找树上排名 inline void Top(int x){
x=pos[x];splay(x,);
if(!st[x].ch[]) return;//如果没有左儿子就不用管了
if(!st[x].ch[]){//没有右儿子就把左儿子挂过去就完事了
st[x].ch[]=st[x].ch[];st[x].ch[]=;return;
}
int ls=st[x].ch[];
int y=find(root,st[ls].size+);//根的rank是st[ls].size+1,st[ls].size+2为根的后继
st[ls].f=y;st[y].ch[]=ls;//根的左子树应该挂在根的后继的左子树
st[x].ch[]=;splay(y,);//最后把更改的点splay到根
return;
}
inline void Bottom(int x){//操作同上,反向操作即可
x=pos[x];splay(x,);
if(!st[x].ch[]) return;
if(!st[x].ch[]){
st[x].ch[]=st[x].ch[];st[x].ch[]=;return;
}
int ls=st[x].ch[];int rs=st[x].ch[];
int y=find(root,st[ls].size);
st[rs].f=y;st[y].ch[]=rs;
st[x].ch[]=;splay(y,);
return;
} inline void change(int x,int y){//题目中的insert操作
x=pos[x];splay(x,);if(!y) return;//如果y==0,说明就不用修改
int ls=st[x].ch[];
if(y==-){//y==-1就找前驱
y=find(root,st[ls].size);
}
else y=find(root,st[ls].size+);//y==1就找后缀
swap(pos[st[x].val],pos[st[y].val]);//这要修改两个点的值和两个点值的所在位置
swap(st[x].val,st[y].val);return;
} inline void rnk(int x){//常规查排名操作
x=pos[x];splay(x,);
int ls=st[x].ch[];
printf("%d\n",st[ls].size);return;
} inline void kth(int x){//常规排名找点操作
x=find(root,x);
printf("%d\n",st[x].val);return;
} int main(){
n=read();m=read();int i,j,k;root=;
for(i=;i<=n;i++){
int x=read();insert(x);
}
//debug=true;
while(m--){
string s;cin>>s;int x,y;
if(s[]=='T'){
x=read();Top(x);
}
if(s[]=='B'){
x=read();Bottom(x);
}
if(s[]=='I'){
x=read();y=read();change(x,y);
}
if(s[]=='A'){
x=read();rnk(x);
}
if(s[]=='Q'){
x=read();kth(x);
}
if(debug){
cout<<"debuging";
output(root);
cout<<endl;
}
}
return ;
}

ZJOI2006 书架 lg2596的更多相关文章

  1. 「luogu2569」[ZJOI2006] 书架

    「luogu2569」[ZJOI2006]书架 题目大意 给定一个长度为 \(n\) 序列,序列中第 \(i\) 个元素有编号 \(a_i(a_i \in \Z \cap [1,n])\),需要支持五 ...

  2. 洛谷 P2596 [ZJOI2006]书架 解题报告

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  3. P2596 [ZJOI2006]书架 && Splay 区间操作(三)

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  4. [Luogu 2596] ZJOI2006 书架

    [Luogu 2596] ZJOI2006 书架 第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦! 省选试机写它,紧张过度失败了. 省选 Day 1 考场写它,写挂了. 省选 Day 1 ...

  5. fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架

    题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...

  6. [ZJOI2006]书架(权值splay)

    [ZJOI2006]书架(luogu) Description 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看 ...

  7. wikioi 1514 and ZJOI2006 书架

    1514 书架 0人推荐 收藏 发题解 提交代码 报错 题目描述 输入描述 输出描述 样例输入 样例输出 提示 题目描述 Description 小 T有一个很大的书柜.这个书柜的构造有些独特,即书柜 ...

  8. [洛谷P2596] [ZJOI2006]书架

    洛谷题目链接:书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后 ...

  9. BZOJ1861:[ZJOI2006]书架

    浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com ...

随机推荐

  1. Oracle导出警告&ldquo;EXP-00003: 未找到段 (0,0) 的存储定义&rdquo;解决

    环境:CentOS7.4   Oracle11.2.0.4(搭建rac集群) 问题描述:在使用exp命令执行导出的时候,部分表提示“EXP-00003: 未找到段 (0,0) 的存储定义”警告. 问题 ...

  2. List集合去重各种方式汇总

    package com.sb.test; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java. ...

  3. Linux下VIM编译器的使用以及shell编程基础

    VIM编译器的安装与使用 vim编辑器安装 在CentOS中,执行:yum -y install vim 普通模式 h: 左移一个字符 j: 下移一行 k: 上移一行 l: 右移一个字符 PageDo ...

  4. MongoDB initial sync过程

    initial sync过程大致如下: (1)T1时间,从Primary同步所有数据库的数据,但不包括local的数据,复制时Mongo会扫描每个源数据库中的每个集合,并将所有数据插入对应的集合.通过 ...

  5. PHP OOP

    <?php //1. Class and object /* object-oriented concept an object can be almost any items or conce ...

  6. @RequestBody 和 @RequestParam(“test”) 的区别与联系

    @RequestBody @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的):GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用 ...

  7. 用友UAP NC 开发环境抛出"JDK默认编辑器找不到"

    此节点是升级65之前开发的,已经很久不使用,今天在开发环境使用,点查询抛出此异常. 最后问了人解决方法,就是往JRE系统库加入对应的jar包

  8. .NET Core 初次上手Swagger

    安装NuGet 程序包=>Swashbuckle.AspNetCore 在  Startup.ConfigureServices  方法里添加注册生成器 //注册Swagger生成器,定义一个和 ...

  9. C++->10.3.6.设有两个按升序排列的二进制文件a和b,将他们合并成一个新的升序二进制数据文件file。

    #include<iostream.h> #include<stdlib.h> #include<string.h> #include<fstream.h&g ...

  10. P5163 WD与地图 [整体二分,强连通分量,线段树合并]

    首先不用说,倒着操作.整体二分来做强连通分量,然后线段树合并,这题就做完了. // powered by c++11 // by Isaunoya #include <bits/stdc++.h ...