Scapegoat_Tree模板和splay模板

来源:互联网 发布:2016淘宝买家可以贷款 编辑:程序博客网 时间:2024/06/06 05:38
#define N (100000+10)const double alpha=0.75;struct Node{    Node *ch[2];    int key,size,cover;// size为有效节点的数量,cover为节点总数量    bool exist;// 是否存在(即是否被删除)     void push_up()    {        size=ch[0]->size+ch[1]->size+(int)exist;        cover=ch[0]->cover+ch[1]->cover+1;    }    bool isBad()    {        return ((ch[0]->cover>cover*alpha+5)||(ch[1]->cover>cover*alpha+5));    }};struct Scapegoat_Tree{    Node mem_poor[N];//内存池,直接分配好避免动态分配内存占用时间     Node *tail,*root,*null;// 用null表示NULL的指针更方便,tail为内存分配指针,root为根     Node *bc[N];// 储存被删除的节点的内存地址,分配时可以再利用这些地址    int bc_top;    Node *New_Node(int key)    {        Node *p=bc_top?bc[--bc_top]:tail++;        p->ch[0]=p->ch[1]=null;        p->size=p->cover=1,p->exist=true;        p->key=key;        return p;    }    void Travel(Node *p,vector<Node*>&v)    {        if (p==null) return;        Travel(p->ch[0],v);        if (p->exist) v.push_back(p);        else bc[bc_top++]=p;        Travel(p->ch[1],v);    }    Node *Divide(vector<Node*>&v,int l,int r)    {        if (l>=r) return null;        int mid=l+r>>1;        Node *p=v[mid];        p->ch[0]=Divide(v,l,mid);        p->ch[1]=Divide(v,mid+1,r);        p->push_up();// 自底向上维护,先维护子树         return p;    }    void Rebuild(Node *&p)    {        static vector <Node*>v;        v.clear();        Travel(p,v);        p=Divide(v,0,v.size());    }    Node **Insert(Node *&p,int val)    {        if (p==null)         {            p=New_Node(val);            return &null;        }        else        {            p->size++;            p->cover++;            // 返回值储存需要重构的位置,若子树也需要重构,本节点开始也需要重构,以本节点为根重构             Node **res=Insert(p->ch[val>=p->key],val);            if (p->isBad()) res=&p;            return res;        }    }    void Erase(Node *p,int id)    {        p->size--;        int offset=p->ch[0]->size+p->exist;        if (p->exist&&id==offset)        {            p->exist=false;            return;        }        else        {            if (id<=offset) Erase(p->ch[0],id);            else Erase(p->ch[1],id-offset);        }    }    void Init()     {        tail=mem_poor;        null=tail++;        null->ch[0]=null->ch[1]=null;        null->cover=null->size=null->key=0;        root=null;        bc_top=0;    }    void Insert(int val)    {        Node **p=Insert(root,val);        if (*p!=null) Rebuild(*p);    }    int Rank(int val)    {        Node *now=root;        int ans=1;        while (now!=null)        { // 非递归求排名             if (now->key>=val) now=now->ch[0];            else            {                ans+=now->ch[0]->size+now->exist;                now=now->ch[1];            }        }        return ans;    }    int Kth(int k)    {        Node *now=root;        while (now!=null)        { // 非递归求第K大             if (now->ch[0]->size+1==k&&now->exist) return now->key;            else if (now->ch[0]->size>=k) now=now->ch[0];            else k-=now->ch[0]->size+now->exist,now=now->ch[1];        }    }    void Erase(int k)    {        Erase(root,Rank(k));        if (root->size<alpha*root->cover) Rebuild(root);    }    void Erase_kth(int k)    {        Erase(root, k);        if (root->size<alpha*root->cover) Rebuild(root);    }}stree;

struct Node{    int key,sz,cnt;    int ch[2],pnt;    Node(){}    Node(int x,int y,int z)    {        key=x,sz=y,cnt=z;    }}a[N<<1];int root,ncnt;void rs(int x){    a[x].sz=a[a[x].ch[0]].sz+a[a[x].ch[1]].sz+a[x].cnt;}void rotate(int x,bool d){    int y=a[x].pnt;    a[y].ch[!d]=a[x].ch[d];    if (a[x].ch[d]!=0) a[a[x].ch[d]].pnt=y;    a[x].pnt=a[y].pnt;    if (a[y].pnt!=0)    {        if (y==a[a[y].pnt].ch[d]) a[a[y].pnt].ch[d]=x;        else a[a[y].pnt].ch[!d]=x;    }    a[x].ch[d]=y;    a[y].pnt=x;    rs(y);    rs(x);}void splay(int x,int target){    int y;    while (a[x].pnt!=target)    {        y=a[x].pnt;        if (x==a[y].ch[0])        {            if (a[y].pnt!=target&&y==a[a[y].pnt].ch[0])rotate(y,true);            rotate(x,true);        }        else        {            if (a[y].pnt!=target&&y==a[a[y].pnt].ch[1])rotate(y,false);            rotate(x,false);        }    }    if (target==0) root=x;}void Insert(int key,int now,int number){    if (root==0)    {        root=now?now:(++ncnt);        a[root].ch[0]=a[root].ch[1]=a[root].pnt=0;        a[root].key=key;        a[root].sz=a[root].cnt=number;        return;    }    int x=root,y;    while (1)    {        a[x].sz+=number;        if (key==a[x].key)        {            a[x].cnt+=number;            a[x].sz+=number;            rs(x);            y=x;            break;        }        else            if (key<a[x].key)            {                if (a[x].ch[0]!=0) x=a[x].ch[0];                else                {                    a[x].ch[0]=now?now:(++ncnt);                    y=a[x].ch[0];                    a[y].key=key;                    a[y].sz=a[y].cnt=number;                    a[y].ch[0]=a[y].ch[1]=0;                    a[y].pnt=x;                    break;                }            }            else            {                if (a[x].ch[1]!=0) x=a[x].ch[1];                else                {                    a[x].ch[1]=now?now:(++ncnt);                    y=a[x].ch[1];                    a[y].key=key;                    a[y].sz=a[y].cnt=number;                    a[y].ch[0]=a[y].ch[1]=0;                    a[y].pnt=x;                    break;                }            }    }    splay(y,0);}int searchmin(int x){    int y=a[x].pnt;    while (a[x].ch[0]!=0) x=a[x].ch[0];    splay(x,y);    return x;}int search(int key){    if (root==0) return 0;    int x=root,y=0;    while (1)    {        if (key==a[x].key) break;        else            if (key>a[x].key)            {                if (a[x].ch[1]!=0) x=a[x].ch[1];                else break;            }            else            {                if (a[x].ch[0]!=0) x=a[x].ch[0];                else break;            }    }    y=x;    splay(x,0);    return y;}int Erase(int key,int number){    if (root==0) return 0;    int x=search(key),y;    if (x==0) return 0;    if (a[x].cnt>number)    {        a[x].cnt-=number;        a[x].sz-=number;        rs(x);        return 0;    }    else        if (a[x].ch[0]==0&&a[x].ch[1]==0)        {            root=0;            return x;        }        else            if (a[x].ch[0]==0)            {                root=a[x].ch[1];                a[a[x].ch[1]].pnt=0;                return x;            }            else                if (a[x].ch[1]==0)                {                    root=a[x].ch[0];                    a[a[x].ch[0]].pnt=0;                    return x;                }    y=searchmin(a[x].ch[1]);    a[y].pnt=0;    a[y].ch[0]=a[x].ch[0];    a[a[x].ch[0]].pnt=y;    rs(y);    root=y;    return x;}int qry_kth(int x,int y){    int now=root;    while (now)    {        if (a[a[now].ch[0]].sz>=x) now=a[now].ch[0];        else         {        if (a[a[now].ch[0]].sz+a[now].cnt<x){x-=a[a[now].ch[0]].sz+a[now].cnt;now=a[now].ch[1];}        else break;}    }    return a[now].key;}


0 0
原创粉丝点击