洛谷P2596 [ZJOI2006]书架(BZOJ1861)
来源:互联网 发布:fcn网络结构 编辑:程序博客网 时间:2024/05/21 22:55
平衡树
洛谷题目传送门
BZOJ题目传送门
初始想法:
对于每个节点,新增一个变量表示当前节点的优先级,用Splay维护。
置顶/置底时先把节点取出,把优先级修改到最大/最小,再插入。
放回时把两个节点取出,交换优先级后插入。
询问的话直接做就好了。
然而打了一个下午没打出来。。。实在太烦了。。。
这时候ZZK飘了过来,看了一眼:“这不是平衡树维护序列裸题吗”
Orz
正解:
Top:把x Splay到根,然后把x的左子树合并到x的后继上。
Bottom:把x Splay到根,然后把x的右子树合并到x的前驱上。
Insert:直接交换x与其前驱/后继的信息。
Ask:把x Splay到根,答案就是它的子树大小。
Query:直接找就好了。
代码:
#include<cstdio>#include<cstring>#include<algorithm>#define N 80000using namespace std;struct node{ int w,size,to[2],fa;}t[N*2+5];int n,m,rt,nd,id[N+5],num[N+5];char s[10];void updt(int x){ t[x].size=t[t[x].to[0]].size+t[t[x].to[1]].size+1; id[num[t[x].to[0]]]=t[x].to[0],id[num[t[x].to[1]]]=t[x].to[1];}void rtt(int x,int &w){ int y=t[x].fa,z=t[y].fa,p=(t[y].to[0]!=x); if (y==w) w=x; else t[z].to[(t[z].to[0]!=y)]=x; t[x].fa=z,t[y].fa=x,t[t[x].to[p^1]].fa=y; t[y].to[p]=t[x].to[p^1],t[x].to[p^1]=y; updt(y),updt(x);}void splay(int x,int &w){ while (x!=w){ int y=t[x].fa,z=t[y].fa; if (y!=w) if ((t[y].to[0]==x)^(t[z].to[0]==y)) rtt(x,w); else rtt(y,w); rtt(x,w); } id[num[x]]=x;}void nsrt(int x){ num[++nd]=x,t[nd].size=1,id[x]=nd,t[nd].to[0]=t[nd].to[1]=0; if (nd>1) t[nd-1].to[1]=nd,t[nd].fa=nd-1,splay(nd,rt);}int srch(int x,int w){ int p=t[x].to[0]; if (t[p].size+1==w) return x; if (t[p].size>=w) return srch(p,w); return srch(t[x].to[1],w-t[p].size-1);}void tp(int x){ x=id[x],splay(x,rt); if (!t[x].to[0]) return; if (!t[x].to[1]) t[x].to[1]=t[x].to[0],t[x].to[0]=0; else{ int p=srch(rt,t[t[x].to[0]].size+2); t[t[rt].to[0]].fa=p,t[p].to[0]=t[rt].to[0]; t[rt].to[0]=0,splay(p,rt); }}void bttm(int x){ x=id[x],splay(x,rt); if (!t[x].to[1]) return; if (!t[x].to[0]) t[x].to[0]=t[x].to[1],t[x].to[1]=0; else{ int p=srch(rt,t[t[x].to[0]].size); t[t[rt].to[1]].fa=p,t[p].to[1]=t[rt].to[1]; t[rt].to[1]=0,splay(p,rt); }}void ns(int x,int w){ if (!w) return; splay(id[x],rt); w++; int p=srch(rt,t[t[id[x]].to[0]].size+w); int x1=num[p],x2=id[x]; swap(id[x],id[x1]); swap(num[x2],num[p]);}int main(){ scanf("%d%d",&n,&m); rt=1; for (int x,i=1;i<=n;i++) scanf("%d",&x),nsrt(x); for (int x,p,i=1;i<=m;i++){ scanf("%s%d",s,&x); switch (s[0]){ case 'T': tp(x); break; case 'B': bttm(x); break; case 'I': scanf("%d",&p),ns(x,p); break; case 'A': x=id[x],splay(x,rt),printf("%d\n",t[t[x].to[0]].size); break; case 'Q': printf("%d\n",num[srch(rt,x)]); break; } } return 0;}
阅读全文
1 0
- 洛谷P2596 [ZJOI2006]书架(BZOJ1861)
- 洛谷 P2596 [ZJOI2006]书架
- [BZOJ1861][ZJOI2006]书架(平衡树splay)
- [BZOJ1861][Zjoi2006]Book 书架
- [BZOJ1861] [Zjoi2006]Book 书架
- bzoj1861: [Zjoi2006]Book 书架
- BZOJ1861: [Zjoi2006]Book 书架
- 【ZJOI2006】bzoj1861 书架
- bzoj1861: [Zjoi2006]Book 书架
- bzoj1861: [Zjoi2006]Book 书架
- bzoj1861 [Zjoi2006]Book 书架
- [BZOJ1861][Zjoi2006]Book 书架 && splay
- 【BZOJ1861】【Zjoi2006】Book 书架 Splay
- 【bzoj1861】[Zjoi2006]Book 书架 splay
- BZOJ1861: [Zjoi2006]Book 书架 Splay
- [bzoj1861][Zjoi2006]Book书架 splay
- 【BZOJ1861】书架(Splay)
- luoguP2596 [ZJOI2006]书架(splay)
- Linux常用命令二
- POJ:1328-Radar Installation
- SpringMVC文件上传与下载
- NYOJ 2 括号配对
- OpenVPN中必须要知道的常用配置项
- 洛谷P2596 [ZJOI2006]书架(BZOJ1861)
- bzoj3438 小M的作物
- 流式布局
- SSM事务管理
- Netty中对象的序列化,反序列化
- 字体旋转,浏览器变小,右边布局移动下面
- 展示数据使用:recyclerview,retrofit,greendao,butterknife,eventbus,fresco。实现效果图列表。MVP模式。
- 自定义view 圆形进度条
- 相似性度量—范数