其他分享
首页 > 其他分享> > 169 可持久化平衡树

169 可持久化平衡树

作者:互联网

视频链接:

Luogu P3835 【模板】可持久化平衡树

#include <iostream>
using namespace std;

const int N=500005;
struct node{
  int l,r; //左右儿子
  int val; //树的权值 
  int rnd; //堆的随机值
  int size; //子树大小
}tr[N*50];
int root[N],idx;

void pushup(int p){ 
  tr[p].size=tr[tr[p].l].size+tr[tr[p].r].size+1;
}
void newnode(int &x,int w){
  x = ++idx;
  tr[x].val=w;
  tr[x].rnd=rand();
  tr[x].size=1;
}
void split(int p,int w,int &x,int &y){
  if(!p) {x=y=0; return;}
  if(tr[p].val<=w){
    x = ++idx; tr[x]=tr[p];
    split(tr[x].r,w,tr[x].r,y);
    pushup(x);
  }
  else{
    y = ++idx; tr[y]=tr[p];
    split(tr[y].l,w,x,tr[y].l);
    pushup(y);
  }
}
int merge(int x,int y){
  if(!x||!y) return x+y;
  int p = ++idx;
  if(tr[x].rnd<tr[y].rnd){
    tr[p]=tr[x];
    tr[p].r=merge(tr[p].r,y);
  }
  else{
    tr[p]=tr[y];
    tr[p].l=merge(x,tr[p].l);
  }
  pushup(p); return p;
}
void insert(int &root,int w){ //插入
  int x,y,z;
  split(root,w,x,y);
  newnode(z,w);
  root=merge(merge(x,z),y);
}
void del(int &root,int w){ //删除
  int x,y,z;
  split(root,w,x,z);
  split(x,w-1,x,y);
  y=merge(tr[y].l,tr[y].r);
  root=merge(merge(x,y),z);
}
int getkth(int &root,int w){ //排名
  int x,y;
  split(root,w-1,x,y);
  int ans=tr[x].size+1;
  root=merge(x,y);
  return ans;
}
int getval(int root,int w){ //数值
  if(w==tr[tr[root].l].size+1)
    return tr[root].val;
  else if(w<=tr[tr[root].l].size)
    return getval(tr[root].l,w);
  else 
    return getval(tr[root].r,w-tr[tr[root].l].size-1);
}
int getpre(int &root,int w){ //前驱
  int x,y,s,ans;
  split(root,w-1,x,y);
  if(!x)return -2147483647;
  s=tr[x].size;
  ans=getval(x,s);
  root=merge(x,y);
  return ans;
}
int getnxt(int &root,int w){ //后继
  int x,y,ans;
  split(root,w,x,y);
  if(!y)return 2147483647;
  else ans=getval(y,1);
  root=merge(x,y);
  return ans;
}
int main(){
  int n,ver,op,w;
  scanf("%d",&n);
  for(int i=1;i<=n;++i){
    scanf("%d%d%d",&ver,&op,&w);
    root[i]=root[ver];
    if(op==1)insert(root[i],w);
    else if(op==2)del(root[i],w);
    else if(op==3)printf("%d\n",getkth(root[i],w));
    else if(op==4)printf("%d\n",getval(root[i],w));
    else if(op==5)printf("%d\n",getpre(root[i],w));
    else printf("%d\n",getnxt(root[i],w));
  }
  return 0;
}

 

标签:持久,val,int,void,tr,rnd,169,平衡,size
来源: https://www.cnblogs.com/dx123/p/16584604.html