带旋平衡树treap(tyvj1728普通平衡树)

    xiaoxiao2022-07-07  197

    平衡树treap(带旋treap)

    带旋treap 注意左右旋转可以合并,d=1时 左儿子上旋至根节点,d==0时右儿子上旋至根节点 代码见下:

    void zhuan(int &x,int d){//旋转,d=1是左儿子上旋 int son=t[x].ch[d]; t[x].ch[d]=t[son].ch[d^1]; t[son].ch[d^1]=x; up(x),up(x=son); }
    有zz问我ac没有,废话,我都发博客了还能没ac吗?(滑稽)

    全部代码见下

    #include<bits/stdc++.h> using namespace std; const int N=1e5+5,inf=0x3f3f3f3f; inline int get(){ int res=0,flag=1;char c=getchar(); while(c<'0'||c>'9'){ if(c=='-')flag=-1; c=getchar(); } while(c>='0'&&c<='9'){ res=res*10+c-'0'; c=getchar(); } return res*flag; } struct node{ int ch[2],cnt,size,val,rd;//依次为左右儿子,有几个这么大的数,根和子节点总个数,值,随机排名 }t[N]; int tot=0; struct treap{ #define ls t[x].ch[0] #define rs t[x].ch[1] void up(int x){//向上更新size t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt; } void zhuan(int &x,int d){//旋转,d=1是左儿子上旋 int son=t[x].ch[d]; t[x].ch[d]=t[son].ch[d^1]; t[son].ch[d^1]=x; up(x),up(x=son); } void insert(int &x,int val){//插入 if(!x){ x=++tot; t[x].cnt=t[x].size=1; t[x].val=val;t[x].rd=rand(); return ; } t[x].size++; if(t[x].val==val){ t[x].cnt++;return; } int d=t[x].val<val;insert(t[x].ch[d],val); if(t[x].rd>t[t[x].ch[d]].rd)zhuan(x,d); } void shan(int &x,int val){//删数 if(!x)return ; if(t[x].val==val){ if(t[x].cnt>1){ t[x].cnt--;t[x].size--; return ; } bool d=t[ls].rd>t[rs].rd; if(!ls||!rs)x=ls+rs; else zhuan(x,d),shan(x,val); } else t[x].size--,shan(t[x].ch[t[x].val<val],val); } int rank(int x,int val){//k的排名 if(!x)return 0; if(t[x].val==val)return t[ls].size+1; if(t[x].val>val)return rank(ls,val); return rank(rs,val)+t[ls].size+t[x].cnt; } int kth(int root,int k){//k大 int x=root; while(1){ if(k<=t[ls].size)x=ls; else if(k>t[ls].size+t[x].cnt) k-=t[ls].size+t[x].cnt,x=rs; else return t[x].val; } } int pre(int x,int val){//前驱 if(!x)return -inf; if(t[x].val>=val)return pre(ls,val); return max(pre(rs,val),t[x].val); } int nxt(int x,int val){//后继 if(!x)return inf; if(t[x].val<=val)return nxt(rs,val); return min(nxt(ls,val),t[x].val); } }tr; int main(){ int n=get(),rt=0; while(n--){ int q=get(),x=get(); if(q==1)tr.insert(rt,x); if(q==2)tr.shan(rt,x); if(q==3)printf("%d\n",tr.rank(rt,x));//注意是rt不是1或0 if(q==4)printf("%d\n",tr.kth(rt,x)); if(q==5)printf("%d\n",tr.pre(rt,x)); if(q==6)printf("%d\n",tr.nxt(rt,x)); } return 0; }

    我wa的点:

    555:

    1、主程序中时rt不是0或1

    2、读优要带负数!!!!!

    完结散花

    最新回复(0)