SBT

SBT(Size Balanced Tree)是陈启峰提出的一种平衡二叉树,下面是 他的论文,中文版的论文 在这里。
SBT树模板
const int maxn = 10000000+10;
struct SBT {
      int l, r, key, s;
      void init(int k) {
            l = r = 0, s = 1, key = k;
      }
}T[maxn];
int next, root, n, m;

void init() {//初始化SBT树的root和next
      next = root = 0;
}
void Right_Rotate(int &t) {//右旋转
      int k = T[t].l;
      T[t].l = T[k].r;
      T[k].r = t;
      T[k].s = T[t].s;
      T[t].s = T[T[t].l].s+T[T[t].r].s+1;
      t = k;
}
void Left_Rotate(int &t) {//左旋转
      int k = T[t].r;
      T[t].r = T[k].l;
      T[k].l = t;
      T[k].s = T[t].s;
      T[t].s = T[T[t].l].s+T[T[t].r].s+1;
      t = k;
}
void Maintain(int &t, bool flag) {//保持SBT树的性质
      if (t==0) return;
      if (!flag) {
            if (T[T[T[t].l].l].s>T[T[t].r].s)
                  Right_Rotate(t);
            else if (T[T[T[t].l].r].s>T[T[t].r].s)
                  Left_Rotate(T[t].l), Right_Rotate(t);
            else return;
      } else {
            if (T[T[T[t].r].r].s>T[T[t].l].s)
                  Left_Rotate(t);
            else if (T[T[T[t].r].l].s>T[T[t].l].s)
                  Right_Rotate(T[t].r), Left_Rotate(t);
            else return;
      }
      Maintain(T[t].l, false);
      Maintain(T[t].r, true);
      Maintain(t, false);
      Maintain(t, true);
}
void Insert(int &t, int key) {
      if (t==0) {//插入结点
            t = ++next;
            T[t].init(key);
      } else {
            T[t].s ++;
            if (key=T[t].key);
}
//删除关键字为key的结点,没有该结点,删除搜索到最后的一个结点
int Delete(int &t, int key) {//删除就是一个覆盖的过程
      T[t].s--;
      if ((T[t].key==key)||(T[t].l==0 && keyT[t].key)) {
            int tmp = T[t].key;
            if (T[t].l==0 || T[t].r==0)//用左儿子(或右儿子)覆盖该结点
                  t = T[t].l+T[t].r;
            else//(T[t].key==key)时的情况用下面的结点覆盖该结点
                  T[t].key = Delete(T[t].l, T[t].key+1);
            return tmp;//返回该结点原来的值
      } else {
            Delete(keyT[t].key)
            return T[T[t].l].s+1+Rank(T[t].r, key);
      else
            return Rank(T[t].l, key);
}
//返回在第k位置上的结点,取最大值Select(t, T[t].s),最小值Select(t, 1)
int Select(int t, int k) {
      if (k==T[T[t].l].s+1)
            return T[t].key;
      else if (k>T[T[t].l].s)
            return Select(T[t].r, k-T[T[t].l].s-1);
      else
            return Select(T[t].l, k);
}
int Pred(int t, int key) {//返回比key小的最大的数
      if (t==0)
            return key;
      if (key<=T[t].key)
            return Pred(T[t].l, key);
      else {
            int tmp = Pred(T[t].r, key);
            return tmp==key?T[t].key:tmp;
      }
}
int Succ(int t, int key) {//返回比key大的最小的数
      if (t==0)
            return key;
      if (key>=T[t].key)
            return Succ(T[t].r, key);
      else {
            int tmp = Succ(T[t].l, key);
            return tmp==key?T[t].key:tmp;
      }
}
void Debug(int t) {
      if (t==0)
            return ;
      Debug(T[t].l);
      printf("%d ", T[t].key);
      Debug(T[t].r);
}
NOI2004 郁闷的出纳员
#include 
#include 
#include 
using namespace std;

const int maxn = 2000000+10;
struct sbt {
      int l, r, s, key;
      void init(int k) {
            l = r = 0, s = 1, key = k;
      }
}T[maxn];
int next, root, n, ans, tmp, Min, d;
char s[11];

void init() {
      next = root = 0;
      tmp = ans = 0;
      T[0].init(0);
      T[0].s = 0;
}
void Right_Rotate(int &t) {
      int k = T[t].l;
      T[t].l = T[k].r;
      T[k].r = t;
      T[k].s = T[t].s;
      T[t].s = T[T[t].l].s+T[T[t].r].s+1;
      t = k;
}
void Left_Rotate(int &t) {
      int k = T[t].r;
      T[t].r = T[k].l;
      T[k].l = t;
      T[k].s = T[t].s;
      T[t].s = T[T[t].l].s+T[T[t].r].s+1;
      t = k;
}
void Maintain(int &t, bool flag) {
      if (!flag) {
            if (T[T[T[t].l].l].s>T[T[t].r].s)
                  Right_Rotate(t);
            else if (T[T[T[t].l].r].s>T[T[t].r].s)
                  Left_Rotate(T[t].l), Right_Rotate(t);
            else return ;
      } else {
            if (T[T[T[t].r].r].s>T[T[t].l].s)
                  Left_Rotate(t);
            else if (T[T[T[t].r].l].s>T[T[t].l].s)
                  Right_Rotate(T[t].r), Left_Rotate(t);
            else return ;
      }
      Maintain(T[t].l, false);
      Maintain(T[t].r, true);
      Maintain(t, false);
      Maintain(t, true);
}
void Insert(int &t, int key) {
      if (t==0) {
            t = ++next;
            T[t].init(key);
      } else {
            T[t].s++;
            if (key=T[t].key);
}
int Delete(int &t, int key) {
      T[t].s--;
      if ((T[t].key==key)||(T[t].l==0 & key=T[t].key)) {
            int tmp = T[t].key;
            if (T[t].l==0 || T[t].r==0)
                  t = T[t].l+T[t].r;
            else
                  T[t].key = Delete(T[t].r, key);
            return tmp;
      } else {
            if (key> n >> Min;
      while (n--) {
            scanf("%s%d", s, &d);
            if (s[0]=='I') {
                  if (d>=Min) {
                        Insert(root, d-tmp);
                  }
            } else if (s[0]=='A') {
                  tmp += d;
            } else if (s[0]=='S') {
                  tmp -= d;
                  while (1) {
                        int qian = Select(root, 1);
                        if ((qian+tmp)T[root].s) {
                        printf("-1\n");
                  } else {
                        printf("%d\n", Select(root, T[root].s-d+1)+tmp);
                  }
            }
      }
      cout << ans << endl;
      return 0;
}
HNOI2002 营业额统计
#include 
#include 
using namespace std;

const int maxn = 1000000+10;
struct sbt {
      int l, r, s, key;
      void init(int k) {
            l = r = 0, s = 1, key = k;
      }
}T[maxn];
int next, root, n, data, ans;

void init() {
      next = root = ans = 0;
      T[0].init(0);
      T[0].s = 0;
}
void Left_Rotate(int &t) {
      int k = T[t].r;
      T[t].r = T[k].l;
      T[k].l = t;
      T[k].s = T[t].s;
      T[t].s = T[T[t].l].s+T[T[t].r].s+1;
      t = k;
}
void Right_Rotate(int &t) {
      int k = T[t].l;
      T[t].l = T[k].r;
      T[k].r = t;
      T[k].s = T[t].s;
      T[t].s = T[T[t].l].s+T[T[t].r].s+1;
      t = k;
}
void Maintain(int &t, bool flag) {
      //if (t==0)
      //      return ;
      if (!flag) {
            if (T[T[T[t].l].l].s>T[T[t].r].s)
                  Right_Rotate(t);
            else if (T[T[T[t].l].r].s>T[T[t].r].s)
                  Left_Rotate(T[t].l), Right_Rotate(t);
            else return ;
      } else {
            if (T[T[T[t].r].r].s>T[T[t].l].s)
                  Left_Rotate(t);
            else if (T[T[T[t].r].l].s>T[T[t].l].s)
                  Right_Rotate(T[t].r), Left_Rotate(t);
            else return ;
      }
      Maintain(T[t].l, false);
      Maintain(T[t].r, true);
      Maintain(t, false);
      Maintain(t, true);
}
void Insert(int &t, int key) {
      if (t==0) {
            t = ++next;
            T[t].init(key);
      } else if (key=T[t].key);
}
int Succ(int t, int key) {
      if (t==0)
            return key;
      if (key>=T[t].key) {
            return Succ(T[t].r, key);
      } else {
            int tmp = Succ(T[t].l, key);
            return tmp==key?T[t].key:tmp;
      }
}
int Pred(int t, int key) {
      if (t==0)
            return key;
      if (key<=T[t].key) {
            return Pred(T[t].l, key);
      } else {
            int tmp = Pred(T[t].r, key);
            return tmp==key?T[t].key:tmp;
      }
}
int Find(int t, int key) {
      if (t==0)
            return 0;
      else if (key==T[t].key) {
            return 1;
      } else if (keyy?y:x;
}

int main()
{
      while (~scanf("%d", &n)) {
            init();
            for (int i=0; i

你可能感兴趣的:(数据结构)