bzoj 3224 普通平衡樹

算是平衡樹最好的入門模板題了,幾乎涵蓋了平衡樹所有的基礎操作.
當然也可以用vector強行亂搞(畢竟暴力出奇跡).

splay

#include<cstdio>
#define N 200005
using namespace std;
int son[N][3],num[N][3],f[N],a[N];
int opt,n,i,root,x,node,ans,flag;
inline void Rotate(int x,int w)//1:左旋;2:右旋 w==1
{
    int y=f[x],z=f[y];
    son[y][3-w]=son[x][w];
    if (son[x][w]) f[son[x][w]]=y;
    f[x]=z;
    num[y][3-w]=num[x][w];
    num[x][w]+=num[y][w]+1;
    if (z)
    {
      if (y==son[z][1]) son[z][1]=x;
      else son[z][2]=x;
    }
    f[y]=x;son[x][w]=y;
}
inline void splay(int x)
{
    int y;
    while (f[x])
    {
        y=f[x];
        if (!f[y])
        {
          if (x==son[y][1]) Rotate(x,2);else Rotate(x,1);
          continue;
        }
        if (y==son[f[y]][1])
        {
          if (x==son[y][1]) Rotate(y,2),Rotate(x,2);
          else Rotate(x,1),Rotate(x,2);
        }
        else
        {
          if (x==son[y][2]) Rotate(y,1),Rotate(x,1);
          else Rotate(x,2),Rotate(x,1);
        }
    }
    root=x;
}
inline void inser(int x,int add)
{
  if (add<=a[x])
  {
    if (!son[x][1]) son[x][1]=++node,a[node]=add,f[node]=x;
    else inser(son[x][1],add);
    num[x][1]++;
  }
  else
  {
    if (!son[x][2]) son[x][2]=++node,a[node]=add,f[node]=x;
    else inser(son[x][2],add);
    num[x][2]++;
  }
}
inline void del(int x,int add)
{
  if (!x) return;
  if (add==a[x])
  {
    splay(x);
    if (!son[x][1]&&!son[x][2]){root=0;return;}
    if (!son[x][1]) {root=son[x][2];f[son[x][2]]=0;return;}
    if (!son[x][2]) {root=son[x][1];f[son[x][1]]=0;return;}
    int find=son[x][1],temp=son[x][2];
    while (son[find][2]) find=son[find][2];
    splay(find);son[find][2]=temp;f[temp]=find;
    return;
  }
  if (add<a[x]) del(son[x][1],add);else del(son[x][2],add);
}
inline int T_T(int x,int add,int now)
{
  inser(root,add);splay(node);
  int ans=num[node][1]+1;
  del(node,add);
  return ans;
}
inline int O_O(int x,int k)
{
  if (k==num[x][1]+1) return a[x];
  if (k<=num[x][1]) return O_O(son[x][1],k);
  return O_O(son[x][2],k-num[x][1]-1);
}
inline int qian(int x,int k)
{
  int find=son[x][1];if (!find) return 0;
  while (son[find][2]) find=son[find][2];
  if (a[find]!=k) flag=1;return find;
}
inline int hou(int x,int k)
{
  int find=son[x][2];if (!find) return 0;
  while (son[find][1]) find=son[find][1];
  if (a[find]!=k) flag=1;return find;
}
int main()
{
    freopen("A.in","r",stdin);
    freopen("A.out","w",stdout);
  scanf("%d",&n);root=0;
  for (i=1;i<=n;i++)
  {
    scanf("%d%d",&opt,&x);
    if (opt==1) inser(root,x),splay(node);
    if (opt==2) del(root,x);
    if (opt==3) printf("%d\n",T_T(root,x,0));
    if (opt==4) printf("%d\n",O_O(root,x));
    if (opt==5)
    {
      inser(root,x);splay(node);
      for (flag=0,ans=qian(root,x);!flag||!ans;splay(ans),ans=qian(root,x));
      del(root,x);printf("%d\n",a[ans]);
    }
    if (opt==6)
    {
      inser(root,x);splay(node);
      for (flag=0,ans=hou(root,x);!flag||!ans;splay(ans),ans=hou(root,x));
      del(root,x);printf("%d\n",a[ans]);
    }
  }
  return 0;
}

treap和vector不怎麼會,如果想知道的話,詳見hzwer的博客.

發佈了25 篇原創文章 · 獲贊 2 · 訪問量 6719
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章