1. 程式人生 > >treap模板

treap模板

-cp fine min -- fde 模板 del memset etc

#include <bits/stdc++.h>
#define For(i, l, r) for(int i = (l), _end_ = (int)(r); i <= _end_; ++i)
#define Fordown(i, r, l) for(int i = (r), _end_ = (int)(l); i >= _end_; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std;

inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}

inline int read() {
    int x = 0, fh = 1; char ch = getchar();
    for (; !isdigit(ch); ch = getchar() ) if (ch == ‘-‘) fh = -1;
    for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ ‘0‘);
    return x * fh;
}

void File() {
#ifdef zjp_shadow
    freopen ("P3369.in", "r", stdin);
    freopen ("P3369.out", "w", stdout);
#endif
}

const int maxnode = 2e6 + 1e3;
int ch[maxnode][2];
int val[maxnode];
int cnt[maxnode], cnt_sum[maxnode];
int prio[maxnode];

struct Treap{
    inline int new_node(int val_) {
        static int len = 0, u;
        u = ++ len;
        ch[u][0] = ch[u][1] = 0;
        val[u] = val_;
        cnt_sum[u] = cnt[u] = 1;
        prio[u] = rand() ;
        return u;
    }

 //   inline void push_up(int u) {
    #define push_up(u) cnt_sum[(u)] = cnt_sum[ch[(u)][0]] + cnt_sum[ch[(u)][1]] + cnt[(u)];
 //   }

    inline void rotate(int &u, int d) {
        int v = ch[u][d];
        ch[u][d] = ch[v][d ^ 1];
        ch[v][d ^ 1] = u;
        push_up(u);
        push_up(v);
        u = v;
    }

    void Out(int u) {
        if (!u) return ;
        Out (ch[u][0]);
        printf ("%d ", val[u]);
        Out (ch[u][1]);
    }

    void Insert(int &u, int val_) {
        if (!u) {
            u = new_node(val_);
            return ;
        }
        if (val[u] == val_)
            ++ cnt[u];
        else {
            int d = (val_ > val[u]);
            Insert(ch[u][d], val_);
            if (prio[ch[u][d]] > prio[u])
                rotate(u, d);
        }
        push_up(u);
    }

    void Erase(int &u) {
        if (!ch[u][0] && !ch[u][1]) {
            u = 0;
            return ;
        }
        int d = (prio[ch[u][1]] > prio[ch[u][0]]);
        rotate(u, d);
        Erase(ch[u][d ^ 1]);
        push_up(u);
    }

    void Delete(int &u, int val_) {
        if (val[u] == val_) {
            if (!(-- cnt[u]) ) Erase(u);
            else push_up(u);
            return ;
        }
        int d = (val_ > val[u]);
        Delete(ch[u][d], val_);
        push_up(u);
    }
    
    int Rank(int u, int val_) {
        if (val[u] == val_)
            return cnt_sum[ch[u][0]];
        int d = (val_ > val[u]);
        return d * (cnt_sum[ch[u][0]] + cnt[u]) + Rank(ch[u][d], val_);
    }

    int Kth(int u, int k) {
        if (k > cnt_sum[ch[u][0]] && k <= cnt_sum[ch[u][0]] + cnt[u]) return val[u];
        int d = (k > cnt_sum[ch[u][0]]);
        k -= d * (cnt_sum[ch[u][0]] + cnt[u]);
        return Kth(ch[u][d], k);
    }

    int Pre(int u, int val_) {
        int res = 0;
        if (!u) return res;
        if (val[u] < val_) res = val[u];
        int d = (val_ > val[u]);
        return max(res, Pre(ch[u][d], val_) );
    }

    int Suf(int u, int val_) {
        int res = 0x7f7f7f7f;
        if (!u) return res;
        if (val[u] > val_) res = val[u];
        int d = (val_ >= val[u]);
        return min(res, Suf(ch[u][d], val_) );
    }
};

Treap T;

int main () {
    File();
    srand(93799);
    static int n = read() ;
    static int root = 0;
    while (n --) {
        static int opt, val_;
        opt = read();
        val_ = read();
        if (opt == 1)
            T.Insert(root, val_);
        if (opt == 2)
            T.Delete(root, val_);
        if (opt == 3)
            printf ("%d\n", T.Rank(root, val_) + 1);
        if (opt == 4) 
            printf ("%d\n", T.Kth(root, val_) );
        if (opt == 5)
            printf ("%d\n", T.Pre(root, val_) );
        if (opt == 6)
            printf ("%d\n", T.Suf(root, val_) );
    }
    return 0;
}

treap模板