博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[bzoj 1861][zjoi2006] 书架
阅读量:6193 次
发布时间:2019-06-21

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

Description

1. Top S——表示把编号为S的书放在最上面。

2. Bottom S——表示把编号为S的书放在最下面。

3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书;

4. Ask S——询问编号为S的书的上面目前有多少本书。

5. Query S——询问从上面数起的第S本书的编号。

Solution

打算用它练习一下\(fhqTreap\)

比较烦的是还要记下每个点的\(fa\)指针,才能计算它的排名

各种修改都是\(split\)然后\(merge\)一下就行了,简单

Code 

#include
#define ll long long#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f;}#define MN 80005class fhqTree{ private: int pri[MN],siz[MN],id[MN],fa[MN],ls[MN],rs[MN],val[MN],rt,sz; inline unsigned int random() { static unsigned int x=23333; return x^=x<<13,x^=x>>17,x^=x<<5; } inline int up(int x){if(ls[x])fa[ls[x]]=x;if(rs[x])fa[rs[x]]=x;return siz[x]=siz[ls[x]]+siz[rs[x]]+1;} inline void Split(int x,int k,int&rt1,int&rt2) { if(!x) return(void)(rt1=rt2=0); if(siz[ls[x]]>=k) Split(ls[x],k,rt1,ls[x]),up(x),rt2=x; else Split(rs[x],k-siz[ls[x]]-1,rs[x],rt2),up(x),rt1=x; } inline int Merge(int rt1,int rt2) { if(!(rt1*rt2)) return rt1|rt2; if(pri[rt1]
r) return;x=++sz;pri[x]=random(); if(l==r) return (void)(siz[x]=1,val[x]=read(),id[val[x]]=x);int mid=(l+r)>>1; Build(ls[x],l,mid-1);val[x]=read();id[val[x]]=x;Build(rs[x],mid+1,r);up(x); } inline int find(int x) { #define get(x) (rs[fa[x]]==x) int res=siz[ls[x]]+1; for(;(x^rt)&&x;x=fa[x]) if(get(x)) res+=siz[ls[fa[x]]]+1; return res; } inline void Output(int x) { if(!x) return; Output(ls[x]);printf("%d %d\n",val[x],val[fa[x]]);Output(rs[x]); } public: inline void build(int n){Build(rt,1,n);} inline void output(){Output(rt);puts("");} inline void Top(int x) { register int k=find(id[x]),rt1,rt2,rt3,rt4; Split(rt,k,rt1,rt2);Split(rt1,k-1,rt3,rt4); rt=Merge(rt4,Merge(rt3,rt2)); } inline void Bottom(int x) { register int k=find(id[x]),rt1,rt2,rt3,rt4; Split(rt,k,rt1,rt2);Split(rt1,k-1,rt3,rt4); rt=Merge(rt3,Merge(rt2,rt4)); } inline void Move(int x,int T) { if(!T) return; register int k=find(id[x]),rt1,rt2,rt3,rt4,rt5,rt6; Split(rt,k,rt1,rt2);Split(rt1,k-1,rt3,rt4); if(T>0) Split(rt2,1,rt5,rt6),rt=Merge(rt3,Merge(rt5,Merge(rt4,rt6))); else Split(rt3,k-2,rt5,rt6),rt=Merge(rt5,Merge(rt4,Merge(rt6,rt2))); } inline void Ask(int x){printf("%d\n",find(id[x])-1);} inline void Query(int k) { register int rt1,rt2,rt3,rt4; Split(rt,k,rt1,rt2);Split(rt1,k-1,rt3,rt4); printf("%d\n",val[rt4]);rt=Merge(rt3,Merge(rt4,rt2)); }}T;int main(){ register int x,n=read(),m=read(),i;T.build(n); register char s[20]; while(m--) { scanf("%s",s);x=read(); if(s[0]=='T') T.Top(x); if(s[0]=='B') T.Bottom(x); if(s[0]=='I') T.Move(x,read()); if(s[0]=='A') T.Ask(x); if(s[0]=='Q') T.Query(x); } return 0;}


Blog来自PaperCloud,未经允许,请勿转载,TKS!

转载于:https://www.cnblogs.com/PaperCloud/p/10271226.html

你可能感兴趣的文章
GoAccess中文界面显示配置
查看>>
final Map可以修改内容,final 常量不能修改
查看>>
“与客户的一次沟通”的所思、所虑、所得
查看>>
什么是内存泄漏
查看>>
homebridge安装问题解决
查看>>
mvn使用哪个jdk?
查看>>
MongoDB安全事件的一些思考
查看>>
云数据库架构演进与实践
查看>>
论学好Linux系统的超级重要性
查看>>
键盘驱动修复
查看>>
hadoop的使用
查看>>
linux的PHP扩展模块安装
查看>>
第八章、bash脚本编程(中)
查看>>
Spring Bean配置默认为单实例 pring Bean生命
查看>>
自定义标签
查看>>
div+css基础总结(二)布局后的准备
查看>>
MySQL事务
查看>>
网络安装Centos 6.6 基本NFS
查看>>
部署与管理ZooKeeper
查看>>
什么是Code Review(转)
查看>>