bzoj3224 Tyvj 1728 普通平衡树 ( 替罪羊树)
来源:互联网 发布:运动keep是什么软件 编辑:程序博客网 时间:2024/05/17 03:04
替罪羊树 模版题
原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3224
题意:
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
数据范围
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
题解:
学习一发替罪羊树。
opt1:直接插入,找插入点到root的链上高度最高的不平衡点重构。
opt2:把他赋为它前驱的值,之后删前驱,前驱最多只有一个儿子就很好删。
opt3~opt6和splay差不多。
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int N=100005;const double Alpha=0.7;const int inf=2147183600;struct node{ int fa,size,ch[2],val;}tr[N];int n,root,tail=0,V[N],top=0;void init(){ tail=2; root=1; tr[1].val=-inf; tr[1].size=2; tr[2].val=inf; tr[2].size=1; tr[1].ch[1]=2; tr[1].fa=0; tr[2].fa=1;}bool balance(int x){ return (double)tr[x].size*Alpha>=(double)tr[tr[x].ch[0]].size &&(double)tr[x].size*Alpha>=(double)tr[tr[x].ch[1]].size;}void getall(int x){ if(tr[x].ch[0]) getall(tr[x].ch[0]); V[++top]=x; if(tr[x].ch[1]) getall(tr[x].ch[1]);}int build(int lf,int rg){ if(lf>rg)return 0; int mid=(lf+rg)>>1; int nd=V[mid]; tr[nd].ch[0]=build(lf,mid-1); if(tr[nd].ch[0]) tr[tr[nd].ch[0]].fa=nd; tr[nd].ch[1]=build(mid+1,rg); if(tr[nd].ch[1]) tr[tr[nd].ch[1]].fa=nd; tr[nd].size=tr[tr[nd].ch[0]].size+tr[tr[nd].ch[1]].size+1; return nd;}void rebuild(int x){ int fa=tr[x].fa; top=0; int opt; if(fa) opt=(tr[fa].ch[1]==x); getall(x); int nd=build(1,top); if(x==root) root=nd; else tr[fa].ch[opt]=nd; tr[nd].fa=fa;}void insert(int val){ int tmp=root; int f=0; int nd=++tail; tr[nd].val=val; tr[nd].size=1; while(1) { tr[tmp].size++; int opt=(val<=tr[tmp].val)? 0:1; f=tmp; tmp=tr[tmp].ch[opt]; if(!tmp) { tr[nd].fa=f; tr[f].ch[opt]=nd; break; } } int pos=0; for(int i=nd;i;i=tr[i].fa) {if(!balance(i)) pos=i;} if(pos) rebuild(pos); }int getpos(int val){ int tmp=root; while(1) { if(tr[tmp].val==val) return tmp; else tmp=tr[tmp].ch[(val>tr[tmp].val)]; } return 0;}void del(int x){ int tmp=x; if(tr[x].ch[0]&&tr[x].ch[1]) { tmp=tr[x].ch[0]; while(tr[tmp].ch[1]) tmp=tr[tmp].ch[1]; tr[x].val=tr[tmp].val; x=tmp; } int fa=tr[tmp].fa; int son=tr[tmp].ch[0]? tr[tmp].ch[0]:tr[tmp].ch[1]; int opt= tr[tr[tmp].fa].ch[0]==tmp? 0:1; if(son) tr[son].fa=fa; if(fa) tr[fa].ch[opt]=son; while(fa) {tr[fa].size--;fa=tr[fa].fa;} if(tmp==root) root=son; }int getrank(int val){ int tmp=root; int ret=0; while(tmp) { if(tr[tmp].val<val) {ret+=tr[tr[tmp].ch[0]].size+1; tmp=tr[tmp].ch[1];} else tmp=tr[tmp].ch[0]; } return ret;}int getkth(int k){ int tmp=root; while(1) { if(tr[tr[tmp].ch[0]].size+1==k) return tr[tmp].val; else if(tr[tr[tmp].ch[0]].size+1>k) tmp=tr[tmp].ch[0]; else {k-=tr[tr[tmp].ch[0]].size+1; tmp=tr[tmp].ch[1];} }}int getpre(int x){ int ans=-inf; int tmp=root; while(tmp) { if(tr[tmp].val>=x) tmp=tr[tmp].ch[0]; else {ans=max(ans,tr[tmp].val); tmp=tr[tmp].ch[1]; } } return ans;}int getnxt(int x){ int ans=inf; int tmp=root; while(tmp) { if(tr[tmp].val<=x) tmp=tr[tmp].ch[1]; else {ans=min(ans,tr[tmp].val); tmp=tr[tmp].ch[0]; } } return ans;}int main(){ scanf("%d",&n); init(); while(n--) { int opt,x; scanf("%d%d",&opt,&x); if(opt==1) insert(x); else if(opt==2) del(getpos(x)); else if(opt==3) printf("%d\n",getrank(x)); else if(opt==4) printf("%d\n",getkth(x+1)); else if(opt==5) printf("%d\n",getpre(x)); else if(opt==6) printf("%d\n",getnxt(x)); } return 0; }
阅读全文
0 0
- bzoj3224 Tyvj 1728 普通平衡树 ( 替罪羊树)
- BZOJ3224: Tyvj 1728 普通平衡树(无旋Treap/替罪羊)
- [Bzoj3224]Tyvj 1728 普通平衡树
- [BZOJ3224]Tyvj 1728 普通平衡树 && treap
- [BZOJ3224]Tyvj 1728 普通平衡树
- 【bzoj3224】Tyvj 1728 普通平衡树
- [BZOJ3224] Tyvj 1728 普通平衡树
- 【bzoj3224】Tyvj 1728 普通平衡树
- 【BZOJ3224】Tyvj 1728 普通平衡树
- bzoj3224: Tyvj 1728 普通平衡树
- bzoj3224 Tyvj 1728 普通平衡树
- 【BZOJ3224】 Tyvj 1728 普通平衡树
- 【bzoj3224】Tyvj 1728 普通平衡树
- 【bzoj3224】Tyvj 1728 普通平衡树
- bzoj3224 Tyvj 1728 普通平衡树 treap
- bzoj3224 Tyvj 1728 普通平衡树
- [TYVJ1728/BZOJ3224]普通平衡树-替罪羊树
- [bzoj3224]普通平衡树 SBT+替罪羊树
- linux学习1
- SQLServer2008把数据导出成可执行的sql脚本
- java8新特性
- 快学Scala-类、对象、继承、特质
- Recyclerview 单行 多行 listView GridView
- bzoj3224 Tyvj 1728 普通平衡树 ( 替罪羊树)
- Wannafly挑战赛4 C割草机 模拟
- android 懒人教程:一步步开发android studio 模板插件
- Android调用摄像头取像
- 3. ROS编程入门—Wall Following
- Top-down design——解决问题的基本法
- android最新版关于.so文件的制作封装与跨平台引用
- NIO详解 五
- 【学习C++】学习C++ -> 构造函数与析构函数