[bzoj1861][Zjoi2006]Book 书架_非旋转Treap
Book 书架 bzoj-1861 Zjoi-2006
题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底);将指定编号元素左右篡位;查询指定编号元素位置;查询指定数量位置元素编号。
注释:$1\le n,m\le 8\cdot 10^4$
想法:非旋转Treap裸题
需要注意的就是那个反复横跳的操作,只需要把指定元素和它接下来要交换的元素都split出来,然后一一合并即可。
最后,附上丑陋的代码... ...
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 80010 #define mp make_pair using namespace std; typedef pair<int,int> par; int n,m,root; int ls[N],rs[N],size[N],key[N],fa[N]; inline void pushup(int x) { size[x]=size[ls[x]]+size[rs[x]]+1; } int merge(int x,int y) { if(!x||!y) return x|y; if(key[x]>key[y]) { rs[x]=merge(rs[x],y);fa[rs[x]]=x; pushup(x); return x; } ls[y]=merge(x,ls[y]);fa[ls[y]]=y; pushup(y); return y; } par split(int x,int k) { if(!k) return mp(0,x); int lson=ls[x],rson=rs[x]; if(k==size[lson]) { ls[x]=0;pushup(x); fa[lson]=0; return mp(lson,x); } if(k==size[lson]+1) { rs[x]=0;pushup(x); fa[rson]=0; return mp(x,rson); } if(k<size[lson]) { par t=split(lson,k); ls[x]=t.second;fa[ls[x]]=x;pushup(x); return mp(t.first,x); } par t=split(rson,k-size[ls[x]]-1); rs[x]=t.first;fa[rs[x]]=x;pushup(x); return mp(x,t.second); } int getid(int x) { int flag=1,t=x,ans=0; while(t) { if(flag)ans+=size[ls[t]]+1; flag=(t==rs[fa[t]]); t=fa[t]; } return ans-1; } int find(int x) { x--;int t=root; while(1) { if(x==size[ls[t]]) return t; if(x<size[ls[t]]) t=ls[t]; else x-=size[ls[t]]+1,t=rs[t]; } } int main() { cin >> n >> m ; for(int x,i=1;i<=n;i++) { scanf("%d",&x); size[x]=1,key[x]=rand()*rand(); root=merge(root,x); } char flag[10]; for(int x,y,i=1;i<=m;i++) { scanf("%s",flag); if(flag[0]=='T') { scanf("%d",&x); int id=getid(x); par t2=split(root,id+1),t1=split(t2.first,id); root=merge(t1.second,merge(t1.first,t2.second)); } else if(flag[0]=='B') { scanf("%d",&x); int id=getid(x); par t2=split(root,id+1),t1=split(t2.first,id); root=merge(merge(t1.first,t2.second),t1.second); } else if(flag[0]=='I') { scanf("%d%d",&x,&y); if(!y)continue; if(y==-1) { int id=getid(x); par t3=split(root,id+1),t2=split(t3.first,id),t1=split(t2.first,id-1); root=merge(merge(merge(t1.first,t2.second),t1.second),t3.second); } else { int id=getid(x); par t3=split(root,id+2),t2=split(t3.first,id+1),t1=split(t2.first,id); root=merge(merge(merge(t1.first,t2.second),t1.second),t3.second); } } else if(flag[0]=='A') { scanf("%d",&x); printf("%d\n",getid(x)); } else { scanf("%d",&x); printf("%d\n",find(x)); } } return 0; }
小结:非旋转Treap就是比splay优(傲娇脸)
| 欢迎来原网站坐坐! >原文链接<