博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【题解】 [ZJOI2006]书架 (Splay)
阅读量:5055 次
发布时间:2019-06-12

本文共 3212 字,大约阅读时间需要 10 分钟。

Solution:

  • 还是一个\(Splay\),我们只用多存一个值\(rad\)来维护二叉树,然后用数组存下每个书对应的值是多少
  • \(Top\)操作,我是把\(s\)旋转到根节点,然后删除,将\(s\)对应的\(rad\)值调至最小,然后插入就可以
  • \(Bottom\)操作,就是和\(Top\)相反,删除后把\(rad\)调整至最大,然后插入
  • \(Insert\)操作,\(s==0\)不用操作,\(-1\)时,就只用把\(s\)旋转到根节点,把左子树最大值旋转至左子树根节点,然后交换两个节点信息,并且交换数组储存的每个书对应的\(rad\)\(1\)就是相反的旋转右子树最小值就可以
  • \(Ask\)操作,就只用把\(s\)旋转到根节点,输出左子树大小
  • \(Query\)操作,就是找第\(s\)大的\(rad\)值对应的书籍编号就可以了
  • 一开始想怎么找编号好久,发现编号是\(1-n\)就好操作了

Code:

//It is coded by Ning_Mew on 4.12#include
#define ls(x) node[x].ch[0]#define rs(x) node[x].ch[1]#define fa(x) node[x].fa#define root node[0].ch[1]using namespace std;const int maxn=8e4+10,INF=1e9+7;int n,m,tot,vall[maxn],low=0,up=0;struct Node{ int fa,ch[2],val,num,size;//num-> bian hao val->rand()}node[maxn];void update(int x){node[x].size=node[ls(x)].size+node[rs(x)].size+1;}void connect(int x,int fa,int how){node[x].fa=fa;node[fa].ch[how]=x;}int ident(int x){return x==node[fa(x)].ch[0]?0:1;}void rorate(int x){ int Y=fa(x),R=fa(Y);int Yson=ident(x),Rson=ident(Y); connect(node[x].ch[Yson^1],Y,Yson); connect(Y,x,Yson^1); connect(x,R,Rson); update(Y);update(x);}void Splay(int x,int goal){ int to=fa(goal); while(fa(x)!=to){ if(fa(fa(x))==to)rorate(x); else if(ident(x)==ident(fa(x)))rorate(fa(x)),rorate(x); else rorate(x),rorate(x); }}int newnode(int x,int rad,int fa){node[++tot].val=rad;node[tot].num=x;node[tot].size=1;node[tot].fa=fa;return tot;}void ins(int x,int rad){ //cout<
<<' '<
<
del 2->swap int pos=find(x,rad); if(!pos)return; if(opt==1){ if(!ls(pos)&&!rs(pos)){root=0;return;} if(!ls(pos)){root=rs(pos);fa(root)=0;return;} else{ int left=ls(pos); while(rs(left))left=rs(left); Splay(left,ls(pos)); connect(rs(pos),left,1); connect(left,0,1);update(left); } }else{ if(sum==0)return; if(sum==-1&&!ls(pos))return; if(sum==1&&!rs(pos))return; if(sum==-1){ int left=ls(pos); while(rs(left))left=rs(left); Splay(left,ls(pos)); swap(vall[ node[pos].num ],vall[ node[left].num ]); swap(node[pos].num,node[left].num); }else{ int right=rs(pos); while(ls(right))right=ls(right); Splay(right,rs(pos)); swap(vall[ node[pos].num ],vall[ node[right].num ]); swap(node[pos].num,node[right].num); } }}int rak(int x,int rad){int pos=find(x,rad);return node[ls(pos)].size;}int kth(int x,int rad){ int now=root; while(1){ if(x-node[ls(now)].size==1){ Splay(now,root);return node[now].num;} int nxt=x<=node[ls(now)].size?0:1; if(nxt){x=x-(node[ls(now)].size+1);} now=node[now].ch[nxt]; }}string s;int main(){ scanf("%d%d",&n,&m); int x,t; for(int i=1;i<=n;i++){ scanf("%d",&x); ins(x,++up);vall[x]=up; } //cout<<"ins finished"<
>s;scanf("%d",&x); if(s=="Top"){ del(x,vall[x],1,0);vall[x]=--low; ins(x,vall[x]); } if(s=="Bottom"){ del(x,vall[x],1,0);vall[x]=++up; ins(x,vall[x]); } if(s=="Insert"){ scanf("%d",&t); del(x,vall[x],2,t); } if(s=="Ask"){printf("%d\n",rak(x,vall[x]));} if(s=="Query"){printf("%d\n",kth(x,vall[x]));} } return 0;}

转载于:https://www.cnblogs.com/Ning-Mew/p/8811015.html

你可能感兴趣的文章
Android反编译后代码阅读
查看>>
gedit乱码问题的解决
查看>>
Java线程工作内存与主内存变量交换过程及volatile关键字理解
查看>>
python 之day4
查看>>
MySQL触发器trigger的使用
查看>>
杂七杂八的面试概念
查看>>
sublime Text 几款插件
查看>>
php xml转数组 自定义xml_to_array
查看>>
python一句话的语法
查看>>
npm 安装less
查看>>
day4 liaoxuefeng---函数式编程
查看>>
第一周作业
查看>>
数据字典/动态性能视图
查看>>
Spring Cloud--实战
查看>>
js中的堆内存和栈内存
查看>>
Nginx 容器
查看>>
Python模块: ConfigParser
查看>>
敏捷外包工程系列之一:序言(敏捷外包工程,敏捷开发,CMMI,软件外包,政府项目,银行项目,电信项目)...
查看>>
linux nfs怪现象——软连接、文件属主的变更
查看>>
三、 添加视图View(ASP.NET MVC5 系列)
查看>>