码风良好的sgt17pts求条,玄两关
查看原帖
码风良好的sgt17pts求条,玄两关
730195
Little_Cabbage楼主2025/2/7 10:57
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

double alpha;

class SGT {
private:
    int tot, w[N], son[N][2], cnt[N], s[N], sz[N], sd[N];
    int a[N];
public:
    int rt;

    void up(int k) {
        s[k] = s[son[k][0]] + s[son[k][1]] + 1;
        sz[k] = sz[son[k][0]] + sz[son[k][1]] + cnt[k];
        sd[k] = sd[son[k][0]] + sd[son[k][1]] + (cnt[k] != 0);
    }

    bool check(int k) {
        return cnt[k] && (alpha * s[k] <= (double)(max(s[son[k][0]], s[son[k][1]])) || (double)(sd[k] <= alpha * s[k]));
    }

    void Split(int &len, int k) {
        if (!k) return ;
        Split(len, son[k][0]);
        if (cnt[k]) a[ ++ len] = k;
        Split(len, son[k][1]);
    }

    int Merge(int l, int r) {
        int mid = l + r >> 1;
        if (l >= r) return 0;
        son[a[mid]][0] = Merge(l, mid - 1);
        son[a[mid]][1] = Merge(mid + 1, r);
        up(a[mid]);
        return a[mid];
    }

    void Build(int &rt) {
        int len = 0;
        Split(len, rt);
        rt = Merge(1, len + 1);
    }

    void Insert(int &k, int x) {
        if (!k) {
            k = ++ tot;
            if (tot == 1) rt = 1;
            w[k] = x;
            son[k][0] = son[k][1] = 0;
            cnt[k] = s[k] = sz[k] = sd[k] = 1;
            return ;
        }
        if (x == w[k]) cnt[k] ++ ;
        else if (x < w[k]) Insert(son[k][0], x);
        else Insert(son[k][1], x);
        up(k);
        if (check(k)) Build(k);
    }

    void Delete(int &k, int x) {
        if (!k) return ;
        if (x == w[k]) {if (cnt[k]) cnt[k] -- ;}
        else if (w[k] < x) Delete(son[k][1], x);
        else Delete(son[k][0], x);
        up(k);
        if (check(k)) Build(k);
    }

    bool find(int x) {
        int p = rt;
        while (p) {
            if (w[p] == x) {
                if (cnt[p]) return true;
                else return false;
            }
            if (w[p] > x) p = son[p][0];
            else p = son[p][1];
        }
        return false;
    }

    int krk(int x) {
        int p = rt;
        while (p) {
            if (w[p] == x) return sd[son[p][0]] + 1;
            if (w[p] > x) p = son[p][0];
            else p = son[p][1];
        }
        return -1;
    }

    int kth(int k, int x) {
        int t = sd[son[k][0]] + 1;
        if (t == x) return w[k];
        if (x < t) return kth(son[k][0], x);
        return kth(son[k][1], x - t);
    }

    int Find(int x) {
        int p = rt;
        while (p) {
            if (w[p] == x) return p;
            if (w[p] > x) p = son[p][0];
            else p = son[p][1];
        }
        return -1;
    }

    int Bound(int k, int p) {
        if (!k) return 1;
        if (w[k] == p && cnt[k]) return sz[son[k][0]] + 1 + cnt[k];
        if (p < w[k]) return Bound(son[k][0], p);
        return sz[son[k][0]] + cnt[k] + Bound(son[k][1], p);
    }

    int Greater(int k, int p)  {
        if (!k) return 0;
        if (w[k] == p && cnt[k]) return sz[son[k][0]];
        if (w[k] < p) return sz[son[k][0]] + cnt[k] + Greater(son[k][1], p);
        return Greater(son[k][0], p);
    }

    int At(int k, int p) {
        if (!k) return 0;
        if (sz[son[k][0]] <= p && p <= sz[son[k][0]] + cnt[k]) return w[k];
        if (sz[son[k][0]] < p) return At(son[k][1], p - sz[son[k][0]] - cnt[k]);
        return At(son[k][0], p);
    }

    int Pred(int x) {
        return At(rt, Greater(rt, x));
    }

    int Succ(int x) {
        return At(rt, Bound(rt, x));
    }
} sgt;

int random(int l, int r) {
    return rand() % (r - l + 1) + l;
}

void Get_alpha() {
    int t = random(1, 3);
    if (t == 1) alpha = 0.659;
    else if (t == 2) alpha = 0.662;
    else alpha = 0.773;
}

int n;

signed main() {
    // struct timeb timeSeed;
	// ftime(&timeSeed);
	// srand(timeSeed.time * 1000 + timeSeed.millitm);
    // Get_alpha();
    alpha = 0.773;
    cin >> n;
    while (n -- ) {
        int op, x;
        cin >> op >> x;
        if (op == 1) sgt.Insert(sgt.rt, x);
        else if (op == 2) sgt.Delete(sgt.rt, x);
        else if (op == 3) {
            bool flag = false;
            if (!sgt.find(x)) {
                flag = true;
                sgt.Insert(sgt.rt, x);
            }
            cout << sgt.krk(x) << "\n";
            if (flag) sgt.Delete(sgt.rt, x);
        } else if (op == 4) cout << sgt.kth(sgt.rt, x) << "\n";
        else if (op == 5) {
            int flag = false;
            if (!sgt.find(x)) {
                flag = true;
                sgt.Insert(sgt.rt, x);
            }
            cout << sgt.Pred(x) << "\n";
            if (flag) sgt.Delete(sgt.rt, x);
        } else {
            int flag = false;
            if (!sgt.find(x)) {
                flag = true;
                sgt.Insert(sgt.rt, x);
            }
            cout << sgt.Succ(x) << "\n";
            if (flag) sgt.Delete(sgt.rt, x);
        }
    }
    return 0;
}
2025/2/7 10:57
加载中...