【Luogu】P2596书架(Splay)
通过这题我加深了对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)的更多相关文章
- P2596 [ZJOI2006]书架 && Splay 区间操作(三)
P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...
- fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架
题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...
- luogu P2596 [ZJOI2006]书架
传送门 感觉要死在\(Splay\)里了 orz 这题用\(Splay\)维护这个序列,其中的第\(k\)大点代表这个序列的第\(k\)个数 第一个操作,先把那个数所在的点旋到根,然后把整个根的左子树 ...
- 洛谷 P2596 [ZJOI2006]书架 (splay)
题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...
- BZOJ 1861: [Zjoi2006]Book 书架 splay
1861: [Zjoi2006]Book 书架 Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书 ...
- BZOJ-1861 Book 书架 Splay
1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 1010 Solved: 588 [Submit][Stat ...
- [题解]bzoj 1861 Book 书架 - Splay
1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1396 Solved: 803[Submit][Stat ...
- [LSGDOJ1822]书架 Splay
题目描述 Sally有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. Sally在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一 ...
- 洛谷.2596.[ZJOI2006]书架(Splay)
题目链接 /* 五个操作: 1.将某元素置顶.删掉这个数,插入最左 2.将某元素置底.同样 3.旋到根后,直接将这个数与前驱/后继交换所有信息 不是左右子节点! 4.5.裸平衡树 ps:1.用pos[ ...
随机推荐
- TC和脚本语言
TC:Turbo C 集成开发环境是由Borland 公司开发的一套C 语言开发工具,它集成了程序编辑.调试.链接等多种功能.在DOS 系统时代,Turbo C 是被最广泛使用的一种PC 机应用程序开 ...
- CF Gym 100637J Superfactorial numeral system (构造)
题意:给一个式子,ak,k>2时,0<=ak<k:ai都是整数,给你p,q让你求一组ak. 题解:构造,每次除掉q取整得到ai,然后减一减 #include<cstdio> ...
- perl -p -i -w -e
.txt kllk nciuwbufcbew``````//.]];s[[..; klklkl x,dsncdk,;l,ex xw,eocxmcmck .txt .txt kkkkkkkkkkkkkk ...
- cocos2dx lua 吞噬层的触摸事件
首先要创建一个layer,设置该层为可触摸 layer:setTouchEnabled(true) 注册触摸事件 local listener = cc.EventListenerTouchOneBy ...
- 【Git版本控制】GitLab Fork项目的工作流程
转载自简书: GitLab Fork项目工作流程
- Mysql中反引号和单引号的区别
反引号,一般在ESC键的下方. 它是为了区分MYSQL的保留字与普通字符而引入的符号.举个例子:SELECT `select` FROM `test` WHERE select='字段值'在test表 ...
- linux系统防火墙关闭
临时关闭防火墙 #systemctl stop firewalld 永久关闭服务端防火墙 #systemctl disabled firewalld getenforce 查询状态 临时 ...
- 学习路由器vue-router
vue-router:vue官方路由管理器. 功能:嵌套的路由/视图表模块化的.基于组件的路由配置路由参数.查询.通配符基于 Vue.js 过渡系统的视图过渡效果细粒度的导航控制带有自动激活的 CSS ...
- destoon模块自定义字段的添加并让其支持搜索的方法
今天看了看模块设置里的自定义字段功能的用法,试着加了个新字段glry,设置了值,然后去数据库moduleid的article表看,字段成功加上了. 于是去template下article文件夹的lis ...
- redis主从+哨兵模式
主从模式配置分为手动和配置文件两种方式进行配置,我现在有192.168.238.128(CentOS1).192.168.238.131(CentOS3).192.168.238.132(CentOS ...