ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

169 可持久化平衡树

2022-08-14 00:01:55  阅读:158  来源: 互联网

标签:持久 val int void tr rnd 169 平衡 size


视频链接:

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有