题目链接

  通过这题我加深了对Splay的理解,原来Splay的子树也是可以接来接去接到别的点上的,而不是只能旋转qwq

  具体接的办法就是swap大法。

  对于Top操作我们把当前节点Splay到根,然后把它的左子树接到后继上。

  Bottom同理

  对于Insert,暴力swap当前节点和它的前驱或者后继。

  Ask操作就把节点Splay到根,然后输出它的左子树有多少节点。

  Query直接查就行。

  

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cstdlib>
#define maxn 1000010
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} int pos[maxn];
int CNT=;
struct Splay{
struct Node{
int key,val,fa,e[],size;
}tree[maxn];
int tag[maxn];
int point,tot,root;
Splay(){point=tot=root=;memset(tag,,sizeof(tag)); }
inline void update(int x){ tree[x].size=tree[tree[x].e[]].size+tree[tree[x].e[]].size+; }
inline void connect(int x,int fa,int how){ tree[x].fa=fa; tree[fa].e[how]=x; }
inline int iden(int x){ return x==tree[tree[x].fa].e[]; }
inline void rotate(int x){
int y=tree[x].fa;int r=tree[y].fa;
if(y==root) root=x;
int sony=iden(x);int sonr=iden(y);
int b=tree[x].e[sony^];
connect(b,y,sony);
connect(y,x,sony^);
connect(x,r,sonr);
update(y); update(x);
}
void splay(int pos,int to){
to=tree[to].fa;
while(tree[pos].fa!=to){
if(tree[tree[pos].fa].fa==to) rotate(pos);
else
if(iden(pos)==iden(tree[pos].fa)){
rotate(tree[pos].fa);
rotate(pos);
}
else{ rotate(pos); rotate(pos); }
}
}
int create(int key,int val,int fa){
tree[++tot].val=val; tree[tot].fa=fa;
tree[tot].size=; tree[tot].key=key;
return tot;
}
int build(int key,int val){
if(root==){ root=create(key,val,); return root; }
int now=root;
while(){
tree[now].size++;
int nxt=tree[now].key>key?:;
if(tree[now].e[nxt]==){
connect(create(key,val,now),now,nxt);
return tot;
}
now=tree[now].e[nxt];
}
}
void insert(int key,int val){
int p=build(key,val);
pos[val]=p;
if(++CNT=){
CNT=;
splay(p,root);
}
}
int find(int rnk){
int now=root;
while(now){
if(tree[tree[now].e[]].size+==rnk) return now;
else if(tree[tree[now].e[]].size>=rnk) now=tree[now].e[];
else{
rnk-=tree[tree[now].e[]].size+;
now=tree[now].e[];
}
}
}
void rotop(int val){
val=pos[val];
splay(val,root);
int le=tree[val].e[];
if(le==) return;
if(tree[val].e[]==){
connect(le,val,);
tree[val].e[]=;
update(val);
}
else{
int deal=find(tree[tree[val].e[]].size+);
connect(tree[val].e[],deal,); tree[val].e[]=;
int now=deal;
while(now){
update(now);
now=tree[now].fa;
}
splay(deal,root);
}
}
void roend(int val){
val=pos[val];
splay(val,root);
int ri=tree[val].e[];
if(ri==) return;
if(tree[val].e[]==){
connect(ri,val,);
tree[val].e[]=;
update(val);
}
else{
int deal=find(tree[tree[val].e[]].size);
connect(tree[val].e[],deal,); tree[val].e[]=;
int now=deal;
while(now){
update(now);
now=tree[now].fa;
}
splay(deal,root);
}
}
void rofro(int val){
val=pos[val];
splay(val,root);
int deal=find(tree[tree[val].e[]].size);
std::swap(pos[tree[val].val],pos[tree[deal].val]);
std::swap(tree[val].val,tree[deal].val);
}
void rosub(int val){
val=pos[val];
splay(val,root);
int deal=find(tree[tree[val].e[]].size+);
std::swap(pos[tree[val].val],pos[tree[deal].val]);
std::swap(tree[val].val,tree[deal].val);
}
int rank(int key){
int now=root;
while(now){
if(tree[tree[now].e[]].size+==key) return tree[now].val;
if(tree[tree[now].e[]].size>=key) now=tree[now].e[];
else{
key-=tree[tree[now].e[]].size+;
now=tree[now].e[];
}
}
return ;
}
int arank(int val){
val=pos[val];
splay(val,root);
return tree[tree[val].e[]].size;
}
}s; int main(){
int n=read(),m=read();
for(int i=;i<=n;++i){
int x=read();
s.insert(i,x);
}
for(int i=;i<=m;++i){
char c[];int x;
scanf("%s%d",c,&x);
switch(c[]){
case 'T':{
s.rotop(x);
break;
}
case 'B':{
s.roend(x);
break;
}
case 'I':{
int y=read();
if(y==-) s.rofro(x);
if(y==) s.rosub(x);
break;
}
case 'A':{
printf("%d\n",s.arank(x));
break;
}
case 'Q':{
printf("%d\n",s.rank(x));
break;
}
}
}
return ;
}

【Luogu】P2596书架(Splay)的更多相关文章

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

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

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

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

  3. luogu P2596 [ZJOI2006]书架

    传送门 感觉要死在\(Splay\)里了 orz 这题用\(Splay\)维护这个序列,其中的第\(k\)大点代表这个序列的第\(k\)个数 第一个操作,先把那个数所在的点旋到根,然后把整个根的左子树 ...

  4. 洛谷 P2596 [ZJOI2006]书架 (splay)

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

  5. BZOJ 1861: [Zjoi2006]Book 书架 splay

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

  6. BZOJ-1861 Book 书架 Splay

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 1010 Solved: 588 [Submit][Stat ...

  7. [题解]bzoj 1861 Book 书架 - Splay

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1396  Solved: 803[Submit][Stat ...

  8. [LSGDOJ1822]书架 Splay

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

  9. 洛谷.2596.[ZJOI2006]书架(Splay)

    题目链接 /* 五个操作: 1.将某元素置顶.删掉这个数,插入最左 2.将某元素置底.同样 3.旋到根后,直接将这个数与前驱/后继交换所有信息 不是左右子节点! 4.5.裸平衡树 ps:1.用pos[ ...

随机推荐

  1. SC || 那些CheckStyle中的错误们

    lab5里给了我们一个checkstyle查代码风格的方法.. 然后 lab4代码 copy一份! 添加checkstyle! 项目 右键 checkstyle!(自信脸) 3s后——7256 war ...

  2. 记录一次mysql中自定义获取UUID的函数

    循环方式一: DELIMITER :; drop function if exists test.fn_test:; create function test.fn_test() ) begin ) ...

  3. springboot 内置tomcat maxPostSizs 无法设置

    ++++++++++++++++++ RT +++++++++++++++++ 如下代码方可解决: /** * tomcat配置类 * 解决post数据体大于2048kb无法接收问题 * 解决tomc ...

  4. Bootstrap历练实例:标签页内的下拉菜单

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  5. Eclipse+Tomcat搭建jsp服务器

    首先,安装java sdk 环境,这里就不多说了,附上java sdk的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk ...

  6. ES6_Promise 对象 阮一锋

    Promise的含义 promise是异步编程的一种解决方法,比传统的回调函数和事件更合理更强大.他由社区最早提出和实现,ES6将其写进语言标准,统一了用法,原生提供了promise对象.所谓prom ...

  7. 【线性基】bzoj2844: albus就是要第一个出场

    线性基求可重rank 题目描述 给定 n 个数 $\{ a_i \}$ ,以及数 $x$. 将 $\{ a_i \}$​ 的所有子集(包括空集)的异或值从小到大排序,得到 $\{ b_i \} $. ...

  8. [LUOGU] P3952 时间复杂度

    其实,也没那么难写 这种模拟题,仔细分析一下输入格式,分析可能的情况,把思路写在纸上,逐步求精,注意代码实现 主要思路就是算一个时间复杂度,和给出的复杂度比较,这就先设计一个函数把给出的复杂度由字符串 ...

  9. MySQL左右连接查询中的NULL的数据筛选问题

    这里使用左连接为例子,对于左连接是将左边表的数据显示,右边表中如果没有对应的数据则使用null填充. game表: game_type表: SELECT g.name,g.type_id,t.type ...

  10. postman测试传入json