第一次打 treap
查看原帖
第一次打 treap
224978
optimize_2楼主2021/7/28 16:21

RT 做了道题 树状数组+离散化被卡了 被迫回来学 treap

#include <bits/stdc++.h>
#define N 100010
#define INF 0x3f3f3f
using namespace std;

class Treap {
  private:
    int val[N], key[N], size[N], count[N];
    int ch[N][2];
    int total;
    #define v(x) val[x]
    #define k(x) key[x]
    #define s(x) size[x]
    #define cnt(x) count[x]
    #define c(x, d) ch[x][d]
    void pushup(int x) {
        s(x) = s(c(x, 0)) + s(c(x, 1));
    }
    void rotate(int &x, int d) {
        int temp = c(x, d ^ 1);
        c(x, d ^ 1) = c(temp, d);
        c(temp, d) = x;
        pushup(x);
        pushup(temp);
        x = temp;
    }
    int create(int v) {
        total++;
        v(total) = v;
        k(total) = rand();
        s(total) = cnt(total) = 1;
        return total;
    }
  public:
    int root;
    void build() {
        root = create(-INF);
        c(root, 1) = create(INF);
        pushup(root);
    }
    void ins(int &x, int v) {
        cout << "INS " << x << " " << v << endl;;
        if (!x) {
            cout << "CRT NODE " << x << endl;
            x = create(v);
            return;
        }
        if (v == v(x)) {
            cnt(x)++;
            return;
        }
        int d = (v >= v(x));
        ins(c(x, d), v);
        if (k(x) < k(c(x, d))) {
            rotate(x, d ^ 1);
        }
        pushup(x);
    }
    void del(int &x, int v) {
        if (!x) return;
        if (v == v(x)) {
            if (cnt(x) > 1) cnt(x)--;
            else if (s(x) == 0) x = 0;
            else {
                int d = !c(x, 1) || v(c(x, 0)) > v(c(x, 1));
                rotate(x, d);
                del(c(x, 2), v);
            }
        } else {
            int d = v > v(x);
            del(c(x, d), v);
        }
        pushup(x);
    }
    int v2k(int x, int v) {
        if (!x) return -2;
        if (v == v(x)) return s(c(x, 0)) + 1;
        else if (v < v(x)) return v2k(c(x, 0), v);
        else return s(c(x, 0)) + cnt(x) + v2k(c(x, 1), v);
    }
    int k2v(int x, int k) {
        if (!x) return INF;
        cout << "K2V " << x << " " << k << " " << s(c(x, 0)) << endl;
        if (k <= s(c(x, 0))) return k2v(c(x, 0), k);
        else if (k <= s(c(x, 0)) + cnt(x)) return v(x);
        else return k2v(c(x, 1), k - s(c(x, 0)) - cnt(x));
    }
    /*
    int k2v(int x,int k){
	    if (!x) return INF;
	    if (k <= s[c(x, 0)]) return k2v(c(x, 0),k);
		else if(k <= s(c(x, 0)) + cnt[x]) return v[x];
	    else return k2v(ch[x][1], k - s[c(x, 0)] - cnt[x]);
	}
    */
    int near(int x, int d) {
        int r = root, near;
        while (r) {
            if (v(r) > x ^ d) {
                near = v(r);
                r = c(r, d ^ 1);
            } else r = c(r, d);
        }
        return near;
    }
};

Treap t;
int n, opt, x;

int main() {
    cin >> n;
    t.build();
    for (int i = 1; i <= n; i++) {
        cin >> opt >> x;
        if (opt == 1) t.ins(t.root, x);
        else if (opt == 2) t.del(t.root, x);
        else if (opt == 3) cout << t.v2k(t.root, x) - 1 << endl;
        else if (opt == 4) cout << t.k2v(t.root, x + 1) << endl;
        else if (opt == 5) cout << t.near(x, 0) << endl;
        else if (opt == 6) cout << t.near(x, 1) << endl;
    }
}

提供调试信息

input:

2
1 1
4 1

output:

INS 1 1
INS 2 1
INS 0 1
CRT NODE 0
K2V 2 2 1
4144959 (0x3f3f3f)

solution-output:

INS 1 1
INS 2 1
INS 0 1
CRT NODE 0
K2V 2 2
K2V 1 2
K2V 3 1
1
2021/7/28 16:21
加载中...