平衡树学习记录

来源:互联网 发布:淘宝发错货赔偿规则 编辑:程序博客网 时间:2024/06/06 03:16

Treap 普通版 -> set

比较函数简化代码很关键

#include <cstdio>#include <cstdlib>#include <ctype.h>#define Magic 19260817#define ll long long#define max(a,b) a>b?a:b#define min(a,b) a<b?a:btemplate<typename T>inline T read(T &f){    f=0;    int x=1;    char c=getchar();    while(!isdigit(c)){if(c=='-')x=-1;c=getchar();}    while(isdigit(c))f=f*10+c-'0',c=getchar();    return f*x;}struct Node{    Node *ch[2];//左右子树     int r;//节点的优先级     int v;//节点的值     int cmp(int x)const{        if(x==v)return -1;        return x<v?0:1;    }//比较函数 };void rotate(Node* &node,int staus){    Node *temp=node->ch[staus^1];    node->ch[staus^1]=temp->ch[staus];    temp->ch[staus]=node;    node=temp;}//旋转 void insert(Node* &node,int x){    if(node==NULL){        node=new Node();        node->ch[0]=node->ch[1]=NULL;        node->v=x;        node->r=rand();    }    else{        int staus=node->cmp(x);        insert(node->ch[staus],x);        if((node->ch[staus])->r > node->r)            rotate(node,staus^1);    }}//插入 void remove(Node* &node,int x){    int staus=node->cmp(x);    if(staus==-1){        if(node->ch[0]==NULL)node=node->ch[1];        else if(node->ch[1]==NULL)node=node->ch[0];        else{            int staus1=(node->ch[0] ->r > node->ch[1] ->r)?1:0;            rotate(node,staus1);            remove(node->ch[staus1],x);        }    }    else        remove(node->ch[staus],x);}//删除 int find(Node* node,int x){    while(node!=NULL){        int staus=node->cmp(x);        if(staus==-1)return 1;        else node=node->ch[staus];    }    return 0;}//查询 Node* root;//根节点 void init(){    root=new Node();    root=new Node();    root->ch[0]=root->ch[1]=NULL;    root->v=0;    root->r=rand();}int n,x;int q,opt;int main(){    srand(Magic);//玄学参数     read(n);    for(int i=1;i<=n;i++){        read(x);        insert(root,x);    }    read(q);    for(int i=1;i<=q;i++){        read(opt);        if(opt==1)            printf("%d\n",find(root,read(x)));        else            remove(root,read(x));    }    return 0;}

Treap - ranktree

#include <cstdio>#include <ctype.h>#include <cstdlib>template <typename T>T read(T &f){    f=0;    int x=1;    char c=getchar();    while(isdigit(c)){if(c=='-')x=-1;c=getchar();}    while(!isdigit(c))f=f*10+c-'0',c=getchar();    return f*x;}#define Magic 19260817struct Node{    Node *ch[2];//左右子树     int r;//优先值     int v;//值     int s;//节点个数     Node(int v=0):v(v){        ch[0]=ch[1]=NULL;        r=rand();        s=1;    }//构造     int cmp(int x)const{        if(x==v)            return -1;        else            return x < v ? 0 : 1;    }//比较函数     void maintain(){        s=1;        if(ch[0]!=NULL)            s+=ch[0]->s;        if(ch[1]!=NULL)            s+=ch[1]->s;    }//更新节点个数 };void rotate(Node* &o,int d){    Node* k=o->ch[d^1];    o->ch[d^1]=k->ch[d];    k->ch[d]=o;    o->maintain();    k->maintain();    o=k;}//旋转 void insert(Node* &o,int x){    if(o==NULL)        o=new Node(x);    else{        int d=(x < o->v ? 0 : 1);        insert(o->ch[d],x);        if(o->ch[d]->r > o->r)            rotate(o,d^1);    }    o->maintain();}//插入 Node* find(Node* o,int x){    if(o==NULL)        return NULL;    if(x==o->v)        return o;    return x < o-> v ? find(o->ch[0],x) : find(o->ch[1],x);}//查找 void remove(Node* &o,int x){    int d=o->cmp(x);    int ret=0;    if(d==-1){        Node* u=o;        if(o->ch[0]!=NULL&&o->ch[1]!=NULL){            int d2=(o->ch[0]->r > o->ch[1]->r ? 1 : 0);            rotate(o,d2);            remove(o->ch[d2],x);        }        else{            if(o->ch[0]==NULL)                o=o->ch[1];            else                o=o->ch[0];        }    }    else        remove(o->ch[d],x);    if(o!=NULL)        o->maintain();}//移除 int kth(Node* o,int k){    if(o==NULL||k<=0||k>o->s)        return 0;    int s=(o->ch[0]==NULL ? 0: o->ch[0]->s);    if(k==s+1)        return o->v;    else if(k<=s)        return kth(o->ch[0],k);    else        return kth(o->ch[1],k-s-1);}//求第k小 int rank(Node* o,int x){    if(o==NULL)        return 1;    if(x<=o->v)        return rank(o->ch[0],x);    else        return rank(o->ch[1],x)+(o->ch[0]==NULL? 0 : o->ch[0]->s)+1;}//求比x小的节点个数 const int INF=1<<28;Node* root= new Node(INF);int m,opt,v;int main(){    scanf("%d",&m);    while(m--){        scanf("%d%d",&opt,&v);        if(opt==1)            insert(root,v);        else if(opt==2){            Node *o=find(root,v);            printf("%d\n",o == NULL ? 0 : 1);            if(o!=NULL)                remove(root,v);        }        else if(opt==3)            printf("%d\n",kth(root,v));        else if(opt==4)            printf("%d\n",rank(root,v));    }    return 0;}

LuoguP3369 【模板】普通平衡树(Treap/SBT)

#include <cstdio>#include <ctype.h>#include <cstdlib>template <typename T>T read(T &f){    f=0;    int x=1;    char c=getchar();    while(isdigit(c)){if(c=='-')x=-1;c=getchar();}    while(!isdigit(c))f=f*10+c-'0',c=getchar();    return f*x;}#define Magic 19260817#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)struct Node{    Node *ch[2];//左右子树     int r;//优先值     int v;//值     int s;//节点个数     Node(int v=0):v(v){        ch[0]=ch[1]=NULL;        r=rand();        s=1;    }//构造     int cmp(int x)const{        if(x==v)            return -1;        else            return x < v ? 0 : 1;    }//比较函数     void maintain(){        s=1;        if(ch[0]!=NULL)            s+=ch[0]->s;        if(ch[1]!=NULL)            s+=ch[1]->s;    }//更新节点个数 };void rotate(Node* &o,int d){    Node* k=o->ch[d^1];    o->ch[d^1]=k->ch[d];    k->ch[d]=o;    o->maintain();    k->maintain();    o=k;}//旋转 void insert(Node* &o,int x){    if(o==NULL)        o=new Node(x);    else{        int d=(x < o->v ? 0 : 1);        insert(o->ch[d],x);        if(o->ch[d]->r > o->r)            rotate(o,d^1);    }    o->maintain();}//插入 Node* find(Node* o,int x){    if(o==NULL)        return NULL;    if(x==o->v)        return o;    return x < o-> v ? find(o->ch[0],x) : find(o->ch[1],x);}//查找 void remove(Node* &o,int x){    int d=o->cmp(x);    int ret=0;    if(d==-1){        Node* u=o;        if(o->ch[0]!=NULL&&o->ch[1]!=NULL){            int d2=(o->ch[0]->r > o->ch[1]->r ? 1 : 0);            rotate(o,d2);            remove(o->ch[d2],x);        }        else{            if(o->ch[0]==NULL)                o=o->ch[1];            else                o=o->ch[0];        }    }    else        remove(o->ch[d],x);    if(o!=NULL)        o->maintain();}//移除 int kth(Node* o,int k){    if(o==NULL||k<=0||k>o->s)        return 0;    int s=(o->ch[0]==NULL ? 0: o->ch[0]->s);    if(k==s+1)        return o->v;    else if(k<=s)        return kth(o->ch[0],k);    else        return kth(o->ch[1],k-s-1);}//求第k小 int rank(Node* o,int x){    if(o==NULL)        return 1;    if(x<=o->v)        return rank(o->ch[0],x);    else        return rank(o->ch[1],x)+(o->ch[0]==NULL? 0 : o->ch[0]->s)+1;}//求比x小的节点个数 void pre(Node* o,int x,int &ans){    if(o==NULL)        return;    if(o->v < x){        ans=max(ans,o->v);        if(o->ch[1]!=NULL)            pre(o->ch[1],x,ans);    }    else if(o->ch[0]!=NULL)        pre(o->ch[0],x,ans);}//求前驱void nxt(Node* o,int x,int &ans){    if(o==NULL)        return;    if(o->v > x){        ans=min(ans,o->v);        if(o->ch[0]!=NULL)            nxt(o->ch[0],x,ans);    }    else if(o->ch[1]!=NULL)        nxt(o->ch[1],x,ans);}//求后继 const int INF=1<<28;Node* root= new Node(INF);int m,opt,v;int ans;int main(){    scanf("%d",&m);    while(m--){        scanf("%d%d",&opt,&v);        if(opt==1)            insert(root,v);//插入         else if(opt==2){            Node *o=find(root,v);            if(o!=NULL)                remove(root,v);        }//删除         else if(opt==3)            printf("%d\n",rank(root,v));//排名         else if(opt==4)            printf("%d\n",kth(root,v));//k大数         else if(opt==5){            ans=0;            pre(root,v,ans);            printf("%d\n",ans);        }//求前驱         else if(opt==6){            ans=INF;            nxt(root,v,ans);            printf("%d\n",ans);        }//求后继     }    return 0;}

待补全

原创粉丝点击