替罪羊树—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 }

 

posted @ 2014-02-23 21:30  zhuohan123  阅读(2910)  评论(0编辑  收藏  举报