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

冬令营被平衡树坑了之后,打算苦练一番数据结构(QAQ)。

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

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

调试小结:

  1.删除操作分两类情况:如果某点只有一个孩子,将它的孩子提上来即可,否则将它变为它的前驱,再删去它的前驱。

  1 #include <iostream>

  2 #include <cstdio>

  3 #include <cstring>

  4 #include <algorithm>

  5 using namespace std;

  6 const double a=0.75;

  7 inline int getnum()

  8 {

  9     int ans=0,fh=1;char ch=getchar();

 10     while(ch<'0'||ch>'9'){if(ch=='-')fh*=-1;ch=getchar();}

 11     while(ch>='0'&&ch<='9')ans=ans*10+ch-'0',ch=getchar();

 12     return fh*ans;

 13 }

 14 struct node{int s[2],f,size,num;}t[2100000];int tnum,root;

 15 inline void init()

 16 {

 17     tnum=2;root=1;

 18     t[1].num=-2147483647;t[1].size=2;t[1].s[1]=2;

 19     t[2].num=2147483647;t[2].size=1;t[2].f=1;

 20 }

 21 inline bool balance(int po)

 22 {

 23     return (double)t[po].size*a>=(double)t[t[po].s[0]].size

 24          &&(double)t[po].size*a>=(double)t[t[po].s[1]].size;

 25 }

 26 int E[210000],esize;

 27 void travel(int po)

 28 {

 29     if(t[po].s[0])travel(t[po].s[0]);

 30     E[++esize]=po;

 31     if(t[po].s[1])travel(t[po].s[1]);

 32 }

 33 int build(int l,int r)

 34 {

 35     if(l>r)return 0;

 36     int mid=(l+r)/2,po=E[mid];

 37     t[t[po].s[0]=build(l,mid-1)].f=po;

 38     t[t[po].s[1]=build(mid+1,r)].f=po;

 39     t[po].size=t[t[po].s[0]].size+t[t[po].s[1]].size+1;

 40     return po;

 41 }

 42 inline void rebuild(int po)

 43 {

 44     esize=0;travel(po);

 45     int fa=t[po].f,ws=(t[t[po].f].s[1]==po);

 46     int npo=build(1,esize);

 47     t[t[fa].s[ws]=npo].f=fa;

 48     if(po==root)root=npo;

 49 }

 50 inline void insert(int num)

 51 {

 52     int now=root,npo=++tnum;

 53     t[npo].size=1;t[npo].num=num;

 54     while(true)

 55     {

 56         t[now].size++;

 57         bool ws=(num>=t[now].num);

 58         if(t[now].s[ws])now=t[now].s[ws];

 59         else {t[t[now].s[ws]=npo].f=now;break ;}

 60     }

 61     int inv=0;

 62     for(int i=npo;i;i=t[i].f)if(!balance(i))inv=i;

 63     if(inv)rebuild(inv);

 64 }

 65 inline int rank(int num)

 66 {

 67     int now=root,ans=0;

 68     while(now)

 69     {

 70         if(t[now].num<num)ans+=t[t[now].s[0]].size+1,now=t[now].s[1];

 71         else now=t[now].s[0];

 72     }

 73     return ans;

 74 }

 75 inline int getkth(int kth)

 76 {

 77     int now=root;

 78     while(true)

 79     {

 80         if(t[t[now].s[0]].size==kth-1)return now;

 81         else if(t[t[now].s[0]].size>=kth)now=t[now].s[0];

 82         else kth-=t[t[now].s[0]].size+1,now=t[now].s[1];

 83     }

 84     return now;

 85 }

 86 inline int getn(int num)

 87 {

 88     int now=root;

 89     while(true)

 90     {

 91         if(t[now].num==num)return now;

 92         else now=t[now].s[t[now].num<num];

 93     }

 94 }

 95 inline void erase(int po)

 96 {

 97     if(t[po].s[0]&&t[po].s[1])

 98     {

 99         int tpo=t[po].s[0];

100         while(t[tpo].s[1])tpo=t[tpo].s[1];

101         t[po].num=t[tpo].num;

102         po=tpo;

103     }

104     int son=(t[po].s[0])?t[po].s[0]:t[po].s[1],ws=(t[t[po].f].s[1]==po);

105     t[t[t[po].f].s[ws]=son].f=t[po].f;

106     for(int i=t[po].f;i;i=t[i].f)t[i].size--;

107     if(po==root)root=son;

108 }

109 inline int succ(int num)

110 {

111     int now=root,ans=2147483647;

112     while(now)

113     {

114         if(t[now].num>num)ans=min(ans,t[now].num),now=t[now].s[0];

115         else now=t[now].s[1];

116     }

117     return ans;

118 }

119 inline int pred(int num)

120 {

121     int now=root,ans=-2147483647;

122     while(now)

123     {

124         if(t[now].num<num)ans=max(ans,t[now].num),now=t[now].s[1];

125         else now=t[now].s[0];

126     }

127     return ans;    

128 }

129 int main(int argc, char *argv[])

130 {

131     init();

132     int n=getnum();

133     for(int i=1;i<=n;i++)

134     {

135         int p=getnum(),num=getnum();

136         if(p==1)insert(num);

137         if(p==2)erase(getn(num));

138         if(p==3)printf("%d\n",rank(num));

139         if(p==4)printf("%d\n",t[getkth(num+1)].num);

140         if(p==5)printf("%d\n",pred(num));

141         if(p==6)printf("%d\n",succ(num));

142     }

143     return 0;

144 }

 

你可能感兴趣的:(ZOJ)