zoukankan      html  css  js  c++  java
  • 替罪羊树—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
    ",rank(num));
    139         if(p==4)printf("%d
    ",t[getkth(num+1)].num);
    140         if(p==5)printf("%d
    ",pred(num));
    141         if(p==6)printf("%d
    ",succ(num));
    142     }
    143     return 0;
    144 }
  • 相关阅读:
    第一篇
    面试题
    CSS样式
    html初步学习
    web开发项目连接访问数据库
    oracle数据库操作之连接
    oracle数据库的基本操作(create创建表,update更新表,drop删除表,select查询表,insert插入数据)
    用js在前台界面进行账户密码的检测,账户和密码符合要求后可进行登录
    用servlet代替js对登录进行检测
    JSP转发和重定向的区别,以及如何获取数据
  • 原文地址:https://www.cnblogs.com/zhuohan123/p/3562539.html
Copyright © 2011-2022 走看看