【bzoj1728】普通平衡树

来源:互联网 发布:淘宝退款要支付宝账号 编辑:程序博客网 时间:2024/04/27 17:28

到现在才想起来我还不会写splay……
QAQ
在DQS学长写模板的时候带了我下……
QAQ人生第一个维护数的splay
QAQQQQQQQ

要记得在del、rot、newnode这种设计更新根的操作的时候一定要root = x;root -> f = null

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int MAXN = 100000 + 5;struct tr{    tr *ch[2],*f;    int v,sz,cnt;    bool dir()    {        return f -> ch[1] == this;    }    void maintain()    {        sz = cnt + ch[0] -> sz + ch[1] -> sz;        return;    }    void setc(tr *p,int d)    {        (ch[d] = p) -> f = this;        return;    }}tree[MAXN],*root,*null;int tot = 0;tr* newnode(int x,tr* fa = null){    tr *p = tree + (tot ++);    p -> f = fa;    p -> ch[0] = p -> ch[1] = null;    p -> sz = p -> cnt = 1;    p -> v = x;    return p;}void reset(){    tot = 0;    null = newnode(0);    null -> sz = null -> cnt = 0;    root = null;    return;}void rot(tr *x){    tr *p = x -> f;    int d = x -> dir();    p -> f -> setc(x,p -> dir());    p -> setc(x -> ch[d ^ 1],d);    p -> maintain();    x -> setc(p,d ^ 1);    x -> maintain();    if(p == root)        root = x;    return;}void splay(tr* x,tr* to = null){    while(x -> f != to)    {        if(x -> f -> f == to)            rot(x);        else            x -> dir() == x -> f -> dir() ? (rot(x -> f),rot(x)) : (rot(x),rot(x));    }}void insert(int x){    if(root == null)    {        root = newnode(x);        return;    }    tr* p = root;    while(p != null)    {        p -> sz ++;        if(p -> v == x)        {            p -> cnt++;            break;        }        int d = x > p -> v;        if(p -> ch[d] == null)        {            p -> ch[d] = newnode(x,p);            p = p -> ch[d];            break;        }        p = p -> ch[d];    }    splay(p);    return;}tr* find(int x){    tr* p = root;    while(p != null)    {        if(p -> v == x)            break;        int d = x > p -> v;        p = p -> ch[d];    }    splay(p);    return p;}void del(int x){    tr *p = find(x);    splay(p);    p -> sz --;    if(--p -> cnt)        return;    if(p -> ch[0] == null){root = p -> ch[1];root -> f = null;return;}    if(p -> ch[1] == null){root = p -> ch[0];root -> f = null;return;}    p = p -> ch[0];    while(p -> ch[1] != null)        p = p -> ch[1];    splay(p,root);    p -> setc(root -> ch[1],1);    p -> f = null;    p -> maintain();    root = p;    return;}int find_hj(int x){    tr* p = root;    int ans = 0;    while(p != null)    {        if(x < p -> v)            ans = p -> v,p = p -> ch[0];        else            p = p -> ch[1];    }    return ans;}int find_qq(int x){    tr* p = root;    int ans = 0;    while(p != null)    {        if(x > p -> v)            ans = p -> v,p = p -> ch[1];        else            p = p -> ch[0];    }    return ans;}int num_to_pm(int x){    splay(find(x));    return root -> ch[0] -> sz + 1;}int pm_to_num(int x){    tr* p = root;    while(p != null)    {        int l = p -> ch[0] -> sz + 1;        int r = p -> ch[0] -> sz + p -> cnt;        if(l <= x && x <= r)            return p -> v;        int d = x > p -> ch[0] -> sz + p -> cnt;        if(d)            x -= p -> ch[0] -> sz + p -> cnt;        p = p -> ch[d];    }    return p -> v;}int n,q,x;int main(){    reset();    scanf("%d",&n);    while(n --)    {        scanf("%d",&q);        switch(q)        {            case 1:scanf("%d",&x);insert(x);break;            case 2:scanf("%d",&x);del(x);break;            case 3:scanf("%d",&x);printf("%d\n",num_to_pm(x));break;            case 4:scanf("%d",&x);printf("%d\n",pm_to_num(x));break;            case 5:scanf("%d",&x);printf("%d\n",find_qq(x));break;            case 6:scanf("%d",&x);printf("%d\n",find_hj(x));break;        }    }    return 0;}
0 0
原创粉丝点击