您的位置:首页 > 其它

替罪羊树—BZOJ3224: Tyvj 1728 普通平衡树

2014-02-23 21:30 375 查看
冬令营被平衡树坑了之后,打算苦练一番数据结构(QAQ)。

先是打了一下想学好久的替罪羊树。

替罪羊树实现方法很简单,就是在不满足平衡条件的时候暴力重构子树。

调试小结:

  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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: