替罪羊树—BZOJ3224: Tyvj 1728 普通平衡树
2014-02-23 21:30
375 查看
冬令营被平衡树坑了之后,打算苦练一番数据结构(QAQ)。
先是打了一下想学好久的替罪羊树。
替罪羊树实现方法很简单,就是在不满足平衡条件的时候暴力重构子树。
调试小结:
1.删除操作分两类情况:如果某点只有一个孩子,将它的孩子提上来即可,否则将它变为它的前驱,再删去它的前驱。
先是打了一下想学好久的替罪羊树。
替罪羊树实现方法很简单,就是在不满足平衡条件的时候暴力重构子树。
调试小结:
1.删除操作分两类情况:如果某点只有一个孩子,将它的孩子提上来即可,否则将它变为它的前驱,再删去它的前驱。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const double a=0.75; inline int getnum() { int ans=0,fh=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')fh*=-1;ch=getchar();} while(ch>='0'&&ch<='9')ans=ans*10+ch-'0',ch=getchar(); return fh*ans; } struct node{int s[2],f,size,num;}t[2100000];int tnum,root; inline void init() { tnum=2;root=1; t[1].num=-2147483647;t[1].size=2;t[1].s[1]=2; t[2].num=2147483647;t[2].size=1;t[2].f=1; } inline bool balance(int po) { return (double)t[po].size*a>=(double)t[t[po].s[0]].size &&(double)t[po].size*a>=(double)t[t[po].s[1]].size; } int E[210000],esize; void travel(int po) { if(t[po].s[0])travel(t[po].s[0]); E[++esize]=po; if(t[po].s[1])travel(t[po].s[1]); } int build(int l,int r) { if(l>r)return 0; int mid=(l+r)/2,po=E[mid]; t[t[po].s[0]=build(l,mid-1)].f=po; t[t[po].s[1]=build(mid+1,r)].f=po; t[po].size=t[t[po].s[0]].size+t[t[po].s[1]].size+1; return po; } inline void rebuild(int po) { esize=0;travel(po); int fa=t[po].f,ws=(t[t[po].f].s[1]==po); int npo=build(1,esize); t[t[fa].s[ws]=npo].f=fa; if(po==root)root=npo; } inline void insert(int num) { int now=root,npo=++tnum; t[npo].size=1;t[npo].num=num; while(true) { t[now].size++; bool ws=(num>=t[now].num); if(t[now].s[ws])now=t[now].s[ws]; else {t[t[now].s[ws]=npo].f=now;break ;} } int inv=0; for(int i=npo;i;i=t[i].f)if(!balance(i))inv=i; if(inv)rebuild(inv); } inline int rank(int num) { int now=root,ans=0; while(now) { if(t[now].num<num)ans+=t[t[now].s[0]].size+1,now=t[now].s[1]; else now=t[now].s[0]; } return ans; } inline int getkth(int kth) { int now=root; while(true) { if(t[t[now].s[0]].size==kth-1)return now; else if(t[t[now].s[0]].size>=kth)now=t[now].s[0]; else kth-=t[t[now].s[0]].size+1,now=t[now].s[1]; } return now; } inline int getn(int num) { int now=root; while(true) { if(t[now].num==num)return now; else now=t[now].s[t[now].num<num]; } } inline void erase(int po) { if(t[po].s[0]&&t[po].s[1]) { int tpo=t[po].s[0]; while(t[tpo].s[1])tpo=t[tpo].s[1]; t[po].num=t[tpo].num; po=tpo; } int son=(t[po].s[0])?t[po].s[0]:t[po].s[1],ws=(t[t[po].f].s[1]==po); t[t[t[po].f].s[ws]=son].f=t[po].f; for(int i=t[po].f;i;i=t[i].f)t[i].size--; if(po==root)root=son; } inline int succ(int num) { int now=root,ans=2147483647; while(now) { if(t[now].num>num)ans=min(ans,t[now].num),now=t[now].s[0]; else now=t[now].s[1]; } return ans; } inline int pred(int num) { int now=root,ans=-2147483647; while(now) { if(t[now].num<num)ans=max(ans,t[now].num),now=t[now].s[1]; else now=t[now].s[0]; } return ans; } int main(int argc, char *argv[]) { init(); int n=getnum(); for(int i=1;i<=n;i++) { int p=getnum(),num=getnum(); if(p==1)insert(num); if(p==2)erase(getn(num)); if(p==3)printf("%d\n",rank(num)); if(p==4)printf("%d\n",t[getkth(num+1)].num); if(p==5)printf("%d\n",pred(num)); if(p==6)printf("%d\n",succ(num)); } return 0; }
相关文章推荐
- 手机通讯录(结构体实现,链表还不会!)
- 常用的webService
- 小孩户口相关
- Ubuntu开机进入文本界面的方法
- 第9课_3_db库安装
- codeforces 390E Inna and Large Sweet Matrix
- Linux学习笔记(五)——Linux系统管理
- 开篇:序
- 开篇:序
- “阿里人”:企业文化与管理就是阿里巴巴的生命!
- Windows应用程序开发记录
- 题目1464:Hello World for U
- 开篇:序
- X宝外包软件测试工程师面试经历
- 电子类笔试题(包括模拟电路、IC基础、数字电路、微机)
- 《30天自制操作系统》学习笔记——第十一天
- bzoj 1833 [ZJOI2010] count 数字计数 题解
- VMWare下虚拟机ubuntu 和 windows文件共享
- 开篇:序
- 题目1202:排序