zoukankan      html  css  js  c++  java
  • splay模板(BZOJ3224)

    用splay实现二叉搜索树的模板,支持插入,删除,找前缀后缀,x的排名以及第x名的数。

    #include <cstdio>
    #define l(x) t[x].s[0]
    #define r(x) t[x].s[1]
    #define f(x) t[x].p
    #define lc(x) (r(f(x)) == x)
    #define st(a,b,c) t[a].s[c] = b; f(b) = a
    
    const int N = 100005;
    int m,x,op,tt,rt;
    struct nd {int v,p,sz,s[2];}t[N];
    
    void pu(int x) {t[x].sz = t[l(x)].sz+t[r(x)].sz+1;}
    void rot(int x) {
        int y = f(x), z = f(y), lx = lc(x), ly = lc(y);
        st(y,t[x].s[!lx],lx); st(z,x,ly); st(x,y,!lx); pu(y);
    }
    void sp(int x) {
        for(int y; y = f(x); rot(x)) if(f(y)) {
            if(lc(x)^lc(y)) rot(x); else rot(y);
        }
        pu(x), rt = x;
    }
    void in(int x) {
        int c = rt;
        while(t[c].s[t[c].v<x]) t[c].sz++, c = t[c].s[t[c].v<x];
        if(c) t[c].sz++; t[c].s[t[c].v<x] = ++tt, f(tt) = c, t[tt].v = x, t[tt].sz = 1, sp(tt);
    }
    void del(int x) {
        int c = rt;
        while(1) {
            if(t[c].v == x) {x = c; break;}
            if(t[c].v < x) c = r(c); else c = l(c);
        } 
        sp(x);
        if(!l(x)) f(r(x)) = 0, rt = r(x);
        else if(!r(x)) f(l(x)) = 0, rt = l(x);
        else {
            f(l(x)) = 0, c = l(x);
            while(r(c)) c = r(c);
            sp(c), r(c) = r(x), f(r(x)) = c;
        }
    }
    int pre(int x) {
        int c = rt, ans = 0xcfcfcfcf;
        while(c) if(t[c].v < x) ans = t[c].v, c = r(c); else c = l(c);
        return ans;
    }
    int nxt(int x) {
        int c = rt, ans = 0x3f3f3f3f;
        while(c) if(t[c].v > x) ans = t[c].v, c = l(c); else c = r(c);
        return ans;
    }
    int rk(int x) {
        int c = rt, k = 0, ans = 0;
        while(c) if(t[c].v < x) ans = k+t[l(c)].sz+1, k += t[l(c)].sz+1, c = r(c); else c = l(c);
        return ans+1;
    }
    int sa(int x, int k) {
        if(t[l(x)].sz == k-1) return t[x].v;
        if(t[l(x)].sz >= k) return sa(l(x), k);
        return sa(r(x), k-t[l(x)].sz-1);
    }
    
    int main() {
        scanf("%d", &m);
        while(m--) {
            scanf("%d%d", &op, &x);
            if(op == 1) in(x);
            else if(op == 2) del(x);
            else if(op == 3) printf("%d
    ", rk(x));
            else if(op == 4) printf("%d
    ", sa(rt,x));
            else if(op == 5) printf("%d
    ", pre(x));
            else printf("%d
    ", nxt(x));
        }
        return 0;
    }
  • 相关阅读:
    稀疏数组
    队列
    链表

    递归
    排序
    查找
    postman设置环境变量
    postman获取全局
    iframe页面刷新问题
  • 原文地址:https://www.cnblogs.com/juruolty/p/6146062.html
Copyright © 2011-2022 走看看