思路

一开始写fhq-treap

感觉越写越感觉splay好些,就去splay

然后维护序列

注意前驱后继的不存在的情况

但不用插入虚拟节点(那插入岂不太麻烦)

跑的真慢的一批,splay太多了

错误

好多错误

只好对拍

代码

//这个题用treap似乎小题大做了,所以我用splay
#include <iostream>
#include <cstdio>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=2e5+7;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,a[maxn],rt,cnt,pos[maxn];
struct node {
int ch[2],fa,val,siz;
}e[maxn];
void pushup(int x) {
e[x].siz=e[e[x].ch[1]].siz+e[e[x].ch[0]].siz+1;
}
void rotate(int x) {
int y=e[x].fa,z=e[y].fa,k=(e[y].ch[1]==x);
e[z].ch[e[z].ch[1]==y]=x;
e[x].fa=z;
e[y].ch[k]=e[x].ch[k^1];
e[e[x].ch[k^1]].fa=y;
e[y].fa=x;
e[x].ch[k^1]=y;
pushup(x),pushup(y);
}
void splay(int x,int goal) {
while(e[x].fa!=goal) {
int y=e[x].fa,z=e[y].fa;
if(z!=goal) (e[y].ch[0]==x)^(e[z].ch[0]==y) ? rotate(x):rotate(y);
rotate(x);
}
if(goal==0) rt=x;
}
int k_th(int k) {
int now=rt;
while(233) {
if(e[e[now].ch[0]].siz+1==k) return e[now].val;
if(e[e[now].ch[0]].siz>=k) now=e[now].ch[0];
else k-=e[e[now].ch[0]].siz+1,now=e[now].ch[1];
}
splay(now,0);
}
int build(int l,int r,int f) {
if(l>r) return 0;
int mid=(l+r)>>1,p=(++cnt);
e[p].fa=f;
e[p].siz=1;
e[p].val=a[mid];
pos[a[mid]]=cnt;
e[p].ch[0]=build(l,mid-1,p);
e[p].ch[1]=build(mid+1,r,p);
pushup(p);
return p;
}
void dfs(int now) {
if(!now) return;
dfs(e[now].ch[0]);
cout<<e[now].val<<" ";
dfs(e[now].ch[1]);
}
int qq(int x) {
splay(x,0);
if(e[rt].val<e[x].val) return rt;
int now=e[rt].ch[0];
if(!now) return 0;
while(e[now].ch[1]) now=e[now].ch[1];
splay(now,0);
return now;
}
int hj(int x) {//x是pos
splay(x,0);
if(e[rt].val>e[x].val) return rt;
int now=e[rt].ch[1];
if(!now) return 0;
while(e[now].ch[0]) now=e[now].ch[0];
splay(now,0);
return now;
}
int p;
void delet(int x) {
int last=qq(x),nxt=hj(x);
if(last) splay(last,0);
if(nxt) splay(nxt,last);
if(nxt==0) {
p=e[last].ch[1];
e[last].ch[1]=0;
} else {
p=e[nxt].ch[0];
e[nxt].ch[0]=0;
if(nxt) splay(nxt,0);
}
}
void insert(int k) {
int now=rt;
while(e[now].ch[k]) now=e[now].ch[k];
e[now].ch[k]=p;
e[p].siz=1;
e[p].fa=now;
splay(p,0);
}
int main() {
n=read(),m=read();
FOR(i,1,n) a[i]=read();
rt=build(1,n,0);
char s[20];
FOR(i,1,m) {
cin>>s;
if(s[0]=='T') {
int a=read();
delet(pos[a]);
insert(0);
} else
if(s[0]=='B') {
int a=read();
delet(pos[a]);
insert(1);
} else
if(s[0]=='I') {
int a=read(),k=read(),b;
if(k==0) continue;
if(k==-1) b=qq(pos[a]);
else b=hj(pos[a]);
if(!b) continue;
int x=a,y=e[b].val;
swap(pos[x],pos[y]);
swap(e[pos[x]].val,e[pos[y]].val);
} else
if(s[0]=='A') {
int a=read();
splay(pos[a],0);
cout<<e[e[rt].ch[0]].siz<<"\n";
} else
if(s[0]=='Q') {
int a=read();
cout<<k_th(a)<<"\n";
}
}
return 0;
}

P2596 [ZJOI2006]书架的更多相关文章

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

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

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

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

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

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

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

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

  5. P2596 [ZJOI2006]书架(splay)

    [题目链接] https://www.luogu.org/problemnew/show/P2596 平衡树,需支持五个操作: 1. 将某元素置顶:将元素旋到根,然后将左子树合并到该元素的后继 2. ...

  6. luogu P2596 [ZJOI2006]书架

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

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

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

  8. 「luogu2569」[ZJOI2006] 书架

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

  9. [Luogu 2596] ZJOI2006 书架

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

随机推荐

  1. uvalive 4452 The Ministers’ Major Mess

    题意: 有一些部长需要对某些账单进行投票. 一个部长最多对4个账单进行投票,且每票对一个账单通过,要么否决. 问是否存在一个方案使得所有部长有超过半数的投票被通过,如果有,那么说明哪些账单的决定是明确 ...

  2. Java解析Json字符串--复杂对象

    { "name": "三班", "students": [ { "age": 25, "gender" ...

  3. GUI带有右键菜单,带有时间显示的

    %带有右键菜单的GUI figure('Menubar','none'); h = uicontextmenu; uimenu(h,'Label','A'); uimenu(h,'Label','B' ...

  4. UVALive 3295 Counting Triangles

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  5. bzoj3196 二逼平衡树

    题目链接 平衡树系列最后一题 坑啊 10s时间限制跑了9764ms...还是要学一学bit套主席树啦... 经典的线段树套treap...至于第一发为什么要TLE(我不会告诉你treap插入的时候忘了 ...

  6. 一个六年Java程序员的从业总结:比起掉发,我更怕掉队

    我一直担惊受怕,过去,可能是因为我年轻,但现在,我已经不是那么年轻了,我仍然发现有很多事情让我害怕. 当年纪越来越大后,我开始变得不能加班.我开始用更多的时间和家人在一起,而不是坐在计算机前(尽管这样 ...

  7. 怎样从外网访问内网WebSphere?

    本地安装了一个WebSphere,只能在局域网内访问,怎样从外网也能访问到本地的WebSphere呢?本文将介绍具体的实现步骤. 准备工作 安装并启动WebSphere 默认安装的WebSphere端 ...

  8. linux中权限对文件和目录的意义

    1.权限对文件的意义: 读:可查看文件的内容 写:可修改文件的内容(但不能删除文件) 执行:可执行文件 2.权限对目录的意义: 读:可以查看目录下的内容,即可以读取该目录下的结构列表 写:可修改目录下 ...

  9. fjwc2019 D1T1 全连(dp+树状数组)

    #178. 「2019冬令营提高组」全连 显然我们可以得出一个$O(n^2)$的dp方程 记$f(i)$为取到第$i$个音符时的最大分数,枚举下一个音符的位置$j$进行转移. 蓝后我们就可以用树状数组 ...

  10. JS使用onscroll、scrollTop实现图片懒加载

    今天做到项目中的图片展示,由于每一页的图片数量都很多,因此需要为图片的展示设计一种懒加载的功能. 第一要做的当然就是给程序添加滚动监听事件. //触发拉取图片开关,保证正在拉取时不能再次触发 var ...