社区讨论
AVL60MLE求救,
P3369【模板】普通平衡树参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lobcrdhg
- 此快照首次捕获于
- 2023/10/29 18:53 2 年前
- 此快照最后确认于
- 2023/11/04 00:36 2 年前
CPP
#include<bits/stdc++.h>
using std::string;
using std::vector;
using std::sort;
using std::cerr;
using std::endl;
typedef long long LL;
typedef unsigned long long ULL;
typedef std::pair<int, int> Pii;
#define fi first
#define se second
namespace FastInput {
template<typename Ty>
void read(Ty &x) { // 默认读入整型 int, LL, Uint, ULL, ...
x = 0;
int f = 0;
char c = getchar();
for (; !isdigit(c); c = getchar()) f |= c == '-';
for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
if (f) x = -x;
}
template<>
void read(double &x) { // 读入浮点型 double
x = 0;
int f = 0;
char c = getchar();
for (; !isdigit(c); c = getchar()) f |= c == '-';
for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
if (c == '.') {
double e = 1;
for (c = getchar(); isdigit(c); c = getchar()) x += (c ^ 48) * (e *= .1);
}
if (f) x = -x;
}
template<>
void read(char &c) { // 读入字符 char
do c = getchar(); while (!isgraph(c));
}
template<>
void read(string &s) { // 读入字符串 string
s = "";
char c = getchar();
while (!isgraph(c)) c = getchar();
for (; isgraph(c); c = getchar()) s += c;
}
template<typename Ty, typename...Args>
void read(Ty &x, Args &...args) { // 不定长传参
read(x);
read(args...);
}
}
using namespace FastInput; // 使用快读
namespace Functions {
template<typename Ty>
inline Ty max(Ty x, Ty y) { return x > y ? x : y; } // 取最大值
template<typename Ty>
inline Ty min(Ty x, Ty y) { return x < y ? x : y; } // 取最小值
template<typename Ty>
inline Ty &Max(Ty &x, Ty y) { return x = max(x, y); } // 赋值取最大值
template<typename Ty>
inline Ty &Min(Ty &x, Ty y) { return x = min(x, y); } // 赋值取最小值
template<typename Ty>
void swap(Ty &x, Ty &y) {
Ty t = x;
x = y;
y = t;
} // 交换
template<typename Pointer>
void reverse(Pointer begin, Pointer end) { // 序列翻转
while (begin < end) swap(*begin++, *--end);
}
}
using namespace Functions; // 使用各种函数
const int N = 100010;
struct AVL {
#define pl tr[p].sn[0]
#define pr tr[p].sn[1]
#define ql tr[q].sn[0]
#define qr tr[q].sn[1]
int pC, rt;
struct Node {
int v, c, sz, h, sn[2];
Node() = default;
Node(int v): v(v), c(1), sz(1), h(1), sn{0, 0} {}
} tr[N];
int newNode(int v) {
tr[++pC] = v;
return pC;
}
void pushUp(int p) {
tr[p].h = max(tr[pl].h, tr[pr].h) + 1;
tr[p].sz = tr[pl].sz + tr[pr].sz + tr[p].c;
}
void rotate(int&p, int ty) {
int q = tr[p].sn[ty];
tr[p].sn[ty] = tr[q].sn[ty ^ 1];
tr[q].sn[ty ^ 1] = p;
pushUp(p); pushUp(p = q);
}
void avl(int&p) {
pushUp(p);
if (abs(tr[pl].h - tr[pr].h) <= 1) return;
int typ = tr[pr].h > tr[pl].h;
int&q = tr[p].sn[typ], tyq = tr[qr].h > tr[ql].h;
if (tyq != typ) rotate(q, tyq);
rotate(p, typ);
}
int kth(int p, int k) {
if (!p) exit(k);
if (k <= tr[pl].sz) return kth(pl, k);
k -= tr[pl].sz;
if (k <= tr[p].c) return tr[p].v;
k -= tr[p].c;
return kth(pr, k);
}
int rank(int p, int v) {
if (v == tr[p].v) return tr[pl].sz + 1;
return v < tr[p].v ? rank(pl, v) : tr[pl].sz + tr[p].c + rank(pr, v);
}
int prv(int p, int v) {
if (!p) return INT_MIN;
return v <= tr[p].v ? prv(pl, v) : max(tr[p].v, prv(pr, v));
}
int nxt(int p, int v) {
if (!p) return INT_MAX;
return v >= tr[p].v ? nxt(pr, v) : min(tr[p].v, nxt(pl, v));
}
void insert(int&p, int v) {
if (!p) return void(p = newNode(v));
if (v == tr[p].v) return void(++tr[p].c);
if (v < tr[p].v) insert(pl, v);
else insert(pr, v);
avl(p);
}
int get(int p, int v) {
if (!tr[p].sn[v > tr[p].v]) return p;
return get(tr[p].sn[v > tr[p].v], v);
}
void erase(int&p, int v, int c) {
if (v < tr[p].v) erase(pl, v, c);
else if (v > tr[p].v) erase(pr, v, c);
else {
if (tr[p].c -= c) return;
if (!pl || !pr) return void(p = pl | pr);
int&s = tr[p].sn[tr[pr].h > tr[pl].h];
int q = get(s, v);
tr[p].v = tr[q].v; tr[p].c = tr[q].c;
erase(s, tr[q].v, tr[q].c);
}
avl(p);
}
#undef pl
#undef pr
#undef ql
#undef qr
} avl;
int main() {
int T; read(T); while (T--) {
int ty, x; read(ty, x);
switch (ty) {
case 1: avl.insert(avl.rt, x); break;
case 2: avl.erase(avl.rt, x, 1); break;
case 3: printf("%d\n", avl.rank(avl.rt, x)); break;
case 4: printf("%d\n", avl.kth(avl.rt, x)); break;
case 5: printf("%d\n", avl.prv(avl.rt, x)); break;
case 6: printf("%d\n", avl.nxt(avl.rt, x)); break;
}
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...