BZOJ 1861 伸展樹基本操作

來源:互聯網
上載者:User

http://www.lydsy.com/JudgeOnline/problem.php?id=1861

寫好關鍵的三個函數後就是水水的類比題,旋轉來旋轉去的操作,so easy

有幾點值得注意:

1:取出Splay中某個節點,然後在插回去,這個節點的左右兒子要記得清空

2:每次更改關係後別忘了up上去

沒了。。

#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <vector>#include <set>#include <algorithm>using namespace std;typedef long long lld;#define L x->c[0]#define R x->c[1]#define KT root->c[1]->c[0]const int maxn = 111111;struct node {    struct node *c[2], *fa;    int id;    int sz;    int val;    inline bool d() {        return fa->c[0] == this;    }    inline void setc(int d, node *s) {        c[d] = s;        s->fa = this;    }    inline void up() {        sz = c[0]->sz + c[1]->sz + 1;    }    inline void clear(node *null) {        c[0] = c[1] = null;        sz = 1;    }} NODE[2 * maxn], *null = &NODE[0] ;int top;node* ID[maxn];struct SplayTree {    node* root;    void Rotate(node *x,int f) {        node *y = x->fa;        y->setc(!f,x->c[f]);        x->fa = y->fa;        if (y->fa != null)    y->fa->setc(!y->d(),x);        x->setc(f,y);        y->up();    }    void Splay(node *x, node *goal) {        while (x->fa != goal) {            if (x->fa->fa == goal)                Rotate(x, x->d());            else {                int f = x->fa->d();                x->d() == f ? Rotate(x->fa, f) : Rotate(x, !f);                Rotate(x, f);            }        }        x->up();        if (goal == null) root = x;    }    void RTO(int k, node *goal) {        if(k<1||k>root->sz) while(1);        node *x = root;        while (L->sz + 1 != k) {            if(k < L->sz + 1) x = L;            else {                k -= L->sz + 1;                x = R;            }        }        Splay(x, goal);    }    void build(node* &x,int l,int r,node *fa) {        if(l > r) return ;        int m = l + r >>1;        x = new_node(fa,num[m]);        build(x->c[0],l,m-1,x);        build(x->c[1],m+1,r,x);        x->up();    }    node *new_node(node *fa, int v) {        node *x = &NODE[++top];        x->id = top;        x->c[0] = x->c[1] = null;        x->sz = 1;        x->val = v;        x->fa = fa;        if(v!=-1) ID[v] = x;        return x;    }    void init(int n) {        for(int i = 1; i <= n; i++) scanf("%d",&num[i]);        root = new_node(null,-1);        build(root->c[1],1,n,root);        root->up();    }    void Del_root() { // delete the root        node* t = root;        if (t->c[1] != null) {            root = t->c[1];            RTO(1, null);            root->c[0] = t->c[0];            if (root->c[0] != null)                root->c[0]->fa = root;        } else            root = root->c[0];        root->fa = null;        if (root != null)            root->up();    }    void Insert(int p,int v) {        Splay(ID[p],null);        int NC = root->c[0]->sz - 1;        Del_root();        ID[p]->clear(null);        NC += v;        RTO(NC+1,null);        if(root->c[1] == null) {            root->setc(1,ID[p]);            root->up();            return ;        }        RTO(NC+2,root);        root->c[1]->setc(0,ID[p]); root->c[1]->up(); root->up();    }    void Bottom(int p) {        Splay(ID[p],null);        Del_root();        ID[p]->clear(null);        RTO(root->sz,null);        root->setc(1,ID[p]); root->up();    }    void Top(int p) {        Splay(ID[p],null);        Del_root();        ID[p]->clear(null);        RTO(1,null);        if(root->c[1] == null) {            root->setc(1,ID[p]);            return ;        }        RTO(2,root);        root->c[1]->setc(0,ID[p]); root->c[1]->up(); root->up();    }    int Query(int p) {        RTO(p+1,null);        return root->val;    }    int Ask(int p) {        Splay(ID[p],null);        return root->c[0]->sz - 1;    }    void vist(node *x) {        if (x != null) {            printf("節點:%2d : 左兒子: %2d  右兒子:  %2d  sz: %2d val: %d\n",                   x->id,x->c[0]->id,x->c[1]->id,x->sz,x->val);            vist(x->c[0]);            vist(x->c[1]);        }    }    void debug() {        puts("************");        vist(root);        puts("\n*****************");    }    int num[maxn];} spt;void prepare() {    top = 0;    null->id = 0;    null->c[0] = null->c[1] = null->fa = NULL;    null->sz = 0;    null->val = 0;}int main() {    char op[10];    prepare();    int n , m , p;    scanf("%d%d",&n,&m);    spt.init(n);    while(m--) {        scanf("%s",op);        if(op[0] == 'Q') {            scanf("%d",&p);            printf("%d\n",spt.Query(p));        } else if(op[0] == 'A') {            scanf("%d",&p);            printf("%d\n",spt.Ask(p));        } else if(op[0] == 'B') {            scanf("%d",&p);            spt.Bottom(p);        } else if(op[0] == 'T') {            scanf("%d",&p);            spt.Top(p);        } else {            int v;            scanf("%d%d",&p,&v);            spt.Insert(p,v);        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.