0516

普通平衡树

/*您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

1 插入 x 数
2 删除 x数(若有多个相同的数,因只删除一个)
3 查询 x 数的排名(排名定义为比当前数小的数的个数 +1 )
4 查询排名为 x 的数
5 求 x 的前驱(前驱定义为小于 x,且最大的数)
6 求 x 的后继(后继定义为大于 x,且最小的数)
7 输入格式
 */

//#pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <climits>
#include <queue>
#include <vector>
#include <stack>
#include <algorithm>
#include <cctype>

#define FAST_IO std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define mem(a, b) memset(a,b,sizeof(a))
#define int long long
#define rint register int
using namespace std;

template<class T>
void tomax(T &a, T b) { a = max(a, b); }

template<class T>
void tomin(T &a, T b) { a = min(a, b); }

typedef long long ll;
typedef pair<int, int> pii;

// #define DEBUG 1
struct IO {
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
    char buf[MAXSIZE], *p1, *p2;
    char pbuf[MAXSIZE], *pp;
#if DEBUG
#else

    IO() : p1(buf), p2(buf), pp(pbuf) {}

    ~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }

#endif

    inline char gc() {
#if DEBUG
        return getchar();
#endif
        if (p1 == p2) p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
        return p1 == p2 ? ' ' : *p1++;
    }

    inline bool blank(char ch) {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }

    template<class T>
    inline void read(T &x) {
        register double tmp = 1;
        register bool sign = 0;
        x = 0;
        register char ch = gc();
        for (; !isdigit(ch); ch = gc())
            if (ch == '-') sign = 1;
        for (; isdigit(ch); ch = gc()) x = x * 10 + (ch - '0');
        if (ch == '.')
            for (ch = gc(); isdigit(ch); ch = gc())
                tmp /= 10.0, x += tmp * (ch - '0');
        if (sign) x = -x;
    }

    inline void read(char *s) {
        register char ch = gc();
        for (; blank(ch); ch = gc());
        for (; !blank(ch); ch = gc()) *s++ = ch;
        *s = 0;
    }

    inline void read(char &c) {
        for (c = gc(); blank(c); c = gc());
    }

    inline void push(const char &c) {
#if DEBUG
        putchar(c);
#else
        if (pp - pbuf == MAXSIZE) fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
        *pp++ = c;
#endif
    }

    template<class T>
    inline void write(T x) {
        if (x < 0) x = -x, push('-');  // 负数输出
        static T sta[35];
        T top = 0;
        do {
            sta[top++] = x % 10, x /= 10;
        } while (x);
        while (top) push(sta[--top] + '0');
    }

    template<class T>
    inline void write(T x, char lastChar) {
        write(x), push(lastChar);
    }
} io;

using namespace std;
#define int long long
#define FAST_IO
const int MAXN = 1e5 + 10;
struct offline {
    int q, x;
} offline[MAXN];
struct Node {
    int l, r, val;
} T[MAXN << 2];
int b[MAXN];
int nums;


void build(int root, int l, int r) {
    T[root].l = l, T[root].r = r, T[root].val = 0;
    if (l == r)return;
    int mid = (l + r) >> 1;
    build(root << 1, l, mid);
    build(root << 1 | 1, mid + 1, r);
}

void pushup(int root) {
    T[root].val = T[root << 1].val + T[root << 1 | 1].val;
}

//$param: 根节点 要更新的数字 要更新的权值
//
void update(int root, int x, int q) {
    if (T[root].l == T[root].r) {
        T[root].val += q;
        return;
    }
    int mid = (T[root].l + T[root].r) >> 1;
    if (x <= mid)update(root << 1, x, q);
    else update(root << 1 | 1, x, q);
    pushup(root);

}

int query(int root, int l, int r) {
    int ans = 0;
    if (T[root].l >= l && T[root].r <= r)return T[root].val;
    int mid = (T[root].l + T[root].r) >> 1;
    if (l <= mid)ans += query(root << 1, l, r);
    if (r > mid) return ans += query(root << 1 | 1, l, r);
    return ans;

}

int dequery(int root, int len) {
    if (T[root].l == T[root].r)return T[root].l;
    if (T[root << 1].val >= len)dequery(root << 1, len);
    else return dequery(root << 1 | 1, len - T[root << 1].val);

}

signed main() {
    int n;
    io.read(n);
    build(1, 1, 1e5);
    for (int i = 1; i <= n; i++) {
        io.read(offline[i].q), io.read(offline[i].x);
        if (offline[i].q != 4) {
            b[++nums] = offline[i].x;
        }
    }
    sort(b + 1, b + 1 + nums);
    //返回最后一个数的下表
    nums = unique(b + 1, b + 1 + nums) - (b + 1);
    for (int i = 1; i <= n; i++) {
        int x = offline[i].x;
        if (offline[i].q != 4) {
            x = lower_bound(b + 1, b + 1 + nums, x) - b;

        }
        int ans;
        switch (offline[i].q) {
            //特定数字权值加一
            case 1:
                update(1, x, 1);
                break;//特定数字权值减一
            case 2:
                update(1, x, -1);
                break;
                //查询x的排名
            case 3:
                ans = query(1, 1, x - 1);
                ans++;
                io.write(ans, '\n');
                break;
                //查询排在第k位的是什么数字
            case 4:
                ans = dequery(1, x);
                io.write(b[ans], '\n');
                break;
                //查询x的前驱数字,先查询x-1的排位,
            case 5:
                ans = query(1, 1, x - 1);
                io.write(b[dequery(1, ans)], '\n');
                break;
                //查询x的后继数字,先查询x的
            case 6:
                ans = query(1, 1, x);
                io.write(b[dequery(1, ans + 1)], '\n');
                break;
        }
    }
    return 0;
}


posted @ 2022-05-17 01:13  ftwftw  阅读(44)  评论(0)    收藏  举报