直接上代码 正所谓 人傻自带大常数

平衡树的几种姿势:  AVL Red&Black_Tree 码量爆炸,不常用;SBT 出于各种原因,不常用。

                                 常用:

                                  Treap 旋转 基于旋转操作和随机数堆 但不支持区间操作。

                                            非旋转 基于随机数堆和拆分合并操作 常数较大 

                                            时间复杂度:很难被卡,均摊O(logN)

#include<cstdio>
#include<iostream>
#include<cstdlib>
#define MAXN 100005
using namespace std;
int ch[MAXN][2],key[MAXN],r[MAXN],size[MAXN],cnt[MAXN],root,sz,n,m;
inline void update(int x)
{
   size[x]=size[ch[x][1]]+size[ch[x][0]]+cnt[x];
}
inline void rotate(int &x)
{
    int wh=r[ch[x][1]]>r[ch[x][0]],son=ch[x][wh];
    ch[x][wh]=ch[son][wh^1];
    ch[son][wh^1]=x;
    update(x);
    update(son);
    x=son;
}
void insert(int &now,int x)
{
    if(!now)
    {
       now=++sz;
       cnt[sz]=size[sz]=1;
       key[sz]=x;
       r[sz]=(rand()%100+rand());
       return;
    }
    if(key[now]==x)
    {
       cnt[now]++;
       size[now]++;
       return;
    }
    insert(ch[now][key[now]<x],x);
    if(r[now]<r[ch[now][key[now]<x]])
      rotate(now);
    else
      update(now);
}
void del(int &now,int x)
{
    if(key[now]==x)
    {
       if(cnt[now]>1)
       {
         cnt[now]--;
         size[now]--;
         return;
       }
       if(ch[now][1]*ch[now][0]==0)
       {
         now=ch[now][1]+ch[now][0];
         return;
       }
       rotate(now);
       del(ch[now][key[ch[now][1]]==x],x);
       update(now);
       return;
    }
    del(ch[now][key[now]<x],x);
    update(now);
}
inline int kth(int x)
{
   int now=root;
   while(1)
   {
      if(size[ch[now][0]]>=x)
      {
        now=ch[now][0];
        continue;
      }
      int lon=cnt[now]+size[ch[now][0]];
      if(lon>=x)
       return key[now];
      x-=lon;
      now=ch[now][1];
   }
}
inline int rank(int x)
{
   int now=root,ans=0;
   while(1)
   {
      if(key[now]==x)
        return ans+1+size[ch[now][0]];
      if(x<key[now])
      {
         now=ch[now][0];
         continue;
      }
      ans+=cnt[now]+size[ch[now][0]];
      now=ch[now][1];
   }
}
inline int pre(int x)
{
   int now=root,ans=-0x7fffffff;
   while(now)
   if(key[now]<x)
   {
      if(key[now]>ans)
       ans=key[now];
      now=ch[now][1];
   }
   else
     now=ch[now][0];
   return ans;
}
inline int next(int x)
{
   int now=root,ans=0x7fffffff;
   while(now)
   if(key[now]>x)
   {
      if(key[now]<ans)
       ans=key[now];
      now=ch[now][0];
   }
   else
     now=ch[now][1];
   return ans;
}
int main()
{
    freopen("phs.in","r",stdin);
    freopen("phs.out","w",stdout);
    scanf("%d",&n);
    while(n--)
    {
       int x,y;
       scanf("%d%d",&y,&x);
       switch(y)
       {
         case 1:insert(root,x);break;
         case 2:del(root,x);break;
         case 3:printf("%d\n",rank(x));break;
         case 4:printf("%d\n",kth(x));break;
         case 5:printf("%d\n",pre(x));break;
         case 6:printf("%d\n",next(x));break;
       }
    }
    return 0;
}
旋转Treap

相关文章:

  • 2022-01-17
  • 2021-09-25
  • 2021-09-12
  • 2021-07-26
  • 2022-01-10
  • 2022-12-23
  • 2021-12-27
  • 2022-02-28
猜你喜欢
  • 2021-07-29
  • 2022-02-07
  • 2022-02-26
  • 2021-09-15
  • 2021-12-24
  • 2021-09-27
  • 2022-02-04
相关资源
相似解决方案