BZOJ 1861: [Zjoi2006]Book 书架
2014-03-04 16:03
489 查看
题目地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1861
题目大意:维护5个操作,具体详见原题(Charlie Pan表示博客写累了~)
算法讨论:
Splay题。
Part I 显然Top和Bottom操作是对称的,我们只需将节点旋转到Root后将左右儿子合并即可。
Part II Insert操作略麻烦……
我的做法是将左/右子树的最大/小值插入到右/左子树中。
具体做法还是利用了Splay操作。
至于其他大神的做法比较神奇,大家可以自行Baidu/Google。
Part III Ask和Query操作时Splay的基本操作,就不一一赘述了。
Code:
By Charlie Pan
Mar 4,2014
题目大意:维护5个操作,具体详见原题(Charlie Pan表示博客写累了~)
算法讨论:
Splay题。
Part I 显然Top和Bottom操作是对称的,我们只需将节点旋转到Root后将左右儿子合并即可。
Part II Insert操作略麻烦……
我的做法是将左/右子树的最大/小值插入到右/左子树中。
具体做法还是利用了Splay操作。
至于其他大神的做法比较神奇,大家可以自行Baidu/Google。
Part III Ask和Query操作时Splay的基本操作,就不一一赘述了。
Code:
/* * Problem:1861 * Author:PYC */ #include <cstdio> #include <algorithm> #define maxn 800000 using namespace std; char ch; int n,m,root,a[maxn+1]; struct node{ int l,r,fa,sz; }tree[maxn+1]; char getopt(){ while (ch!='T' && ch!='B' && ch!='I' && ch!='A' && ch!='Q') ch=getchar(); return ch; } int getint(){ while (ch!='-' && (ch<'0' || ch>'9')) ch=getchar(); int x=0; bool f=0; if (ch=='-') f=1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); if (f) x=-x; return x; } void up(int rt){ tree[rt].sz=tree[tree[rt].l].sz+tree[tree[rt].r].sz+1; } void build(int &rt,int l,int r){ int mid=(l+r)/2; rt=a[mid]; tree[rt].sz=r-l+1; if (mid-l) build(tree[rt].l,l,mid-1),tree[tree[rt].l].fa=rt; if (r-mid) build(tree[rt].r,mid+1,r),tree[tree[rt].r].fa=rt; } int min_node(int rt){ if (!tree[rt].l) return rt; return min_node(tree[rt].l); } int max_node(int rt){ if (!tree[rt].r) return rt; return max_node(tree[rt].r); } void zig(int rt){ int t=tree[rt].l; tree[rt].l=tree[t].r; tree[t].r=rt; tree[t].fa=tree[rt].fa; tree[rt].fa=t; tree[tree[rt].l].fa=rt; if (rt==tree[tree[t].fa].l) tree[tree[t].fa].l=t;else tree[tree[t].fa].r=t; up(rt); up(t); } void zag(int rt){ int t=tree[rt].r; tree[rt].r=tree[t].l; tree[t].l=rt; tree[t].fa=tree[rt].fa; tree[rt].fa=t; tree[tree[rt].r].fa=rt; if (rt==tree[tree[t].fa].l) tree[tree[t].fa].l=t;else tree[tree[t].fa].r=t; up(rt); up(t); } void splay(int x,int &rt){ int fa=tree[rt].fa; while (tree[x].fa!=fa){ int y=tree[x].fa,z=tree[y].fa; if (z==fa) if (x==tree[y].l) zig(y);else zag(y); else if (y==tree[z].l) if (x==tree[y].l) zig(z),zig(y);else zag(y),zig(z); else if (x==tree[y].r) zag(z),zag(y);else zig(y),zag(z); } rt=x; } void top(int x){ splay(x,root); if (tree[root].r){ splay(min_node(tree[root].r),tree[root].r); tree[tree[root].r].l=tree[root].l; tree[tree[root].l].fa=tree[root].r; tree[root].l=0; } else{ tree[root].r=tree[root].l; tree[root].l=0; } up(tree[root].r); up(root); } void bottom(int x){ splay(x,root); if (tree[root].l){ splay(max_node(tree[root].l),tree[root].l); tree[tree[root].l].r=tree[root].r; tree[tree[root].r].fa=tree[root].l; tree[root].r=0; } else{ tree[root].l=tree[root].r; tree[root].r=0; } up(tree[root].l); up(root); } void insert(int x,int mode){ if (!mode) return; splay(x,root); if (!tree[root].l && !tree[root].r) return; if (tree[root].l) splay(max_node(tree[root].l),tree[root].l); if (tree[root].r) splay(min_node(tree[root].r),tree[root].r); if (mode==1){ if (tree[root].l){ int rr=tree[tree[root].r].r; tree[tree[root].r].r=0; tree[tree[root].r].sz=1; tree[tree[root].l].r=tree[root].r; tree[tree[root].r].fa=tree[root].l; tree[root].r=rr; tree[tree[root].r].fa=root; } else{ int rr=tree[tree[root].r].r; tree[tree[root].r].r=0; tree[tree[root].r].sz=1; tree[root].l=tree[root].r; tree[root].r=rr; tree[tree[root].r].fa=root; } up(tree[root].l); up(root); } if (mode==-1){ if (tree[root].r){ int ll=tree[tree[root].l].l; tree[tree[root].l].l=0; tree[tree[root].l].sz=1; tree[tree[root].r].l=tree[root].l; tree[tree[root].l].fa=tree[root].r; tree[root].l=ll; tree[tree[root].l].fa=root; } else{ int ll=tree[tree[root].l].l; tree[tree[root].l].l=0; tree[tree[root].l].sz=1; tree[root].r=tree[root].l; tree[root].l=ll; tree[tree[root].l].fa=root; } up(tree[root].r); up(root); } } int ask(int x){ splay(x,root); return tree[tree[root].l].sz; } int query(int rt,int x){ if (x==tree[tree[rt].l].sz+1) return rt; if (x<tree[tree[rt].l].sz+1) return query(tree[rt].l,x); if (x>tree[tree[rt].l].sz+1) return query(tree[rt].r,x-tree[tree[rt].l].sz-1); } int main(){ n=getint(),m=getint(); for (int i=1;i<=n;++i) a[i]=getint(); build(root,1,n); for (int i=1;i<=m;++i){ char opt=getopt(); int x=getint(); if (opt=='T') top(x); if (opt=='B') bottom(x); if (opt=='I'){int y=getint();insert(x,y);} if (opt=='A') printf("%d\n",ask(x)); if (opt=='Q') printf("%d\n",query(root,x)); } return 0; }
By Charlie Pan
Mar 4,2014
相关文章推荐
- BZOJ 1861 [Zjoi2006]Book 书架
- bzoj1861: [Zjoi2006]Book 书架 平衡树 Splay
- bzoj 1861 [Zjoi2006]Book 书架
- BZOJ 1861: [Zjoi2006]Book 书架
- BZOJ 1861 [Zjoi2006]Book 书架 ——Splay
- BZOJ 1861 ZJOI 2006 Book 书架 Splay
- BZOJ 1861: [Zjoi2006]Book 书架 (splay)
- BZOJ_1861_[Zjoi2006]Book 书架_splay
- BZOJ1861: [Zjoi2006]Book 书架
- BZOJ 1861 [Zjoi2006] Book 书架
- 【权值分块】bzoj1861 [Zjoi2006]Book 书架
- [bzoj1861][Zjoi2006]Book书架 splay
- [bzoj1861][Zjoi2006]Book 书架_非旋转Treap
- BZOJ 1861: [Zjoi2006]Book 书架( splay )
- bzoj1861: [Zjoi2006]Book 书架
- bzoj 1861 [Zjoi2006]Book 书架
- [BZOJ1861][Zjoi2006]Book 书架 && splay
- BZOJ1861 [Zjoi2006]Book 书架
- 【平衡树】【pb_ds】 bzoj1861 [Zjoi2006]Book 书架
- BZOJ1861: [Zjoi2006]Book 书架