可持久化平衡树

Posted segmenttree

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可持久化平衡树相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=510000;
const int Log=50; 
const int inf=2147483647;
int val[N*Log],rnd[N*Log],lo[N*Log],ro[N*Log],sz[N*Log],tot;
int st[N],top=0;
int root[N];
int rd()
{
  int w=1,ber=0;
  char op;
  for(op=getchar();op<‘0‘||op>‘9‘;op=getchar()) if(op==‘-‘) w=-1;
  for(;‘0‘<=op&&op<=‘9‘;op=getchar()) ber=ber*10+op-‘0‘;
  return ber*w;
}
int ne()
{
  if(top>0) return st[top--];
  return ++tot;
}
int ned(int va)
{
  int p=ne();
  rnd[p]=rand();
  val[p]=va;
  sz[p]=1;
  lo[p]=ro[p]=0;
  return p;
}
int coy(int p)
{
  int q=ne();
  rnd[q]=rnd[p],val[q]=val[p],lo[q]=lo[p],ro[q]=ro[p],sz[q]=sz[p];
  return q;
}
inline void up(int p)
{
  sz[p]=sz[lo[p]]+sz[ro[p]]+1;
  return;
}
int merge(int a,int b)
{
  if(!a||!b) return a+b;
  int p;
  if(rnd[a]<rnd[b])
  {
    p=coy(a);
    ro[p]=merge(ro[p],b),up(p);
    return p;
  }
  p=coy(b);
  lo[p]=merge(a,lo[p]),up(p);
  return p;
}
inline void spilt(int u,int k,int &x,int &y)
{
  if(!u){x=y=0;return;}
  if(val[u]<=k) 
  {
    x=coy(u);
    spilt(ro[x],k,ro[x],y);
    up(x);
  }
  else 
  {
    y=coy(u);
    spilt(lo[y],k,x,lo[y]);
    up(y);
  }
  return;
}
inline void ins(int &rt,int x)
{
  int a,b,c=ned(x);
  spilt(rt,x,a,b);
  rt=merge(a,merge(c,b));
  return;
}
inline void era(int &rt,int x)
{
  int a,b,c;
  spilt(rt,x-1,a,b);
  spilt(b,x,b,c);
  if(sz[b]>0) st[++top]=b,b=merge(lo[b],ro[b]);
  rt=merge(a,merge(b,c));
  return;
}
int kth(int u,int k)
{
  if(sz[lo[u]]+1==k) return val[u];
  else if(k>sz[lo[u]]+1) return kth(ro[u],k-sz[lo[u]]-1);
  return kth(lo[u],k);
}
int ran(int &rt,int k)
{
  int a,b;
  spilt(rt,k-1,a,b);
  int rk=sz[a]+1;
  rt=merge(a,b);
  return rk;
}
int bef(int &rt,int x)
{
  int a,b;
  spilt(rt,x-1,a,b);
  int now=-inf;
  if(sz[a]>0) now=kth(a,sz[a]);
  rt=merge(a,b);
  return now;
}
int aft(int &rt,int x)
{
  int a,b;
  spilt(rt,x,a,b);
  int now=inf;
  if(sz[b]>0) now=kth(b,1);
  rt=merge(a,b);
  return now;  
}

int n;
int main()
{
  srand(time(NULL));
  n=rd();
  int tim,op,x;
  for(register int i=1;i<=n;i++)
  {
    tim=rd(),op=rd(),x=rd();
    root[i]=root[tim];
    if(op==1) ins(root[i],x);
    else if(op==2) era(root[i],x);
    else if(op==3) printf("%d
",ran(root[i],x));
    else if(op==4) printf("%d
",kth(root[i],x));
    else if(op==5) printf("%d
",bef(root[i],x));
    else printf("%d
",aft(root[i],x));
  }
  return 0;
}

以上是关于可持久化平衡树的主要内容,如果未能解决你的问题,请参考以下文章

可持久化平衡树

[luogu3835]可持久化平衡树

可持久化平衡树

P3919 模板可持久化数组(可持久化线段树/平衡树)

平衡树与可持久化treap

luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)