社区讨论
帮我看看这个复杂度为啥不对
P6136【模板】普通平衡树(数据加强版)参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mdhaxcv9
- 此快照首次捕获于
- 2025/07/24 19:20 7 个月前
- 此快照最后确认于
- 2025/11/04 03:48 4 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
mt19937_64 mrand(time(0));
template<int N>
struct FHQ_Treap {
struct Node {
int val, sz;
int l, r;
} node[N + 1];
int cnt, rt;
void init() {
cnt = rt = 0;
}
int new_node(int val) {
node[++cnt] = {val, 1, 0, 0};
return cnt;
}
void update(int id) {
node[id].sz = 1;
if (node[id].l)
node[id].sz += node[node[id].l].sz;
if (node[id].r)
node[id].sz += node[node[id].r].sz;
}
void split(int rt, int key, int &l, int &r) {
if (!rt) {
l = r = 0;
return;
} else {
if (node[rt].val <= key) {
l = rt;
split(node[rt].r, key, node[rt].r, r);
} else {
r = rt;
split(node[rt].l, key, l, node[rt].l);
}
update(rt);
}
}
int merge(int l, int r) {
if (!l)
return r;
else if (!r)
return l;
else if (mrand() & 1) {
node[l].r = merge(node[l].r, r);
update(l);
return l;
} else {
node[r].l = merge(l, node[r].l);
update(r);
return r;
}
}
void insert(int x) {
int now = new_node(x);
int l = 0, r = 0;
split(rt, x, l, r);
rt = merge(merge(l, now), r);
}
void erase(int x) {
int l = 0, r = 0, mid = 0;
split(rt, x, l, r);
split(l, x - 1, l, mid);
mid = merge(node[mid].l, node[mid].r);
rt = merge(merge(l, mid), r);
}
int rank(int x) {
int l = 0, r = 0;
split(rt, x - 1, l, r);
int ret = node[l].sz;
rt = merge(l, r);
return ret + 1;
}
int kth(int k) {
int now = rt;
while (true) {
if (node[node[now].l].sz >= k)
now = node[now].l;
else if (node[node[now].l].sz == k - 1)
return node[now].val;
else {
k -= node[node[now].l].sz + 1;
now = node[now].r;
}
}
return 0;
}
int pre(int x) {
int l = 0, r = 0;
split(rt, x - 1, l, r);
int tmp = l;
while (node[tmp].r)
tmp = node[tmp].r;
rt = merge(l, r);
return node[tmp].val;
}
int nxt(int x) {
int l = 0, r = 0;
split(rt, x, l, r);
int tmp = r;
while (node[tmp].l)
tmp = node[tmp].l;
rt = merge(l, r);
return node[tmp].val;
}
};
FHQ_Treap<1100000> treap;
int n, m;
int main() {
scanf("%d%d", &n, &m);
treap.init();
for (int i = 1; i <= n; i++) {
int tmp;
cin >> tmp;
treap.insert(tmp);
}
int lst = 0, ans = 0;
for (int i = 1; i <= m; i++) {
int opt, x;
scanf("%d%d", &opt, &x);
x ^= lst;
if (opt == 1)
treap.insert(x);
else if (opt == 2)
treap.erase(x);
else if (opt == 3)
ans ^= (lst = treap.rank(x));
else if (opt == 4)
ans ^= (lst = treap.kth(x));
else if (opt == 5)
ans ^= (lst = treap.pre(x));
else
ans ^= (lst = treap.nxt(x));
}
printf("%d\n", ans);
return 0;
}
该代码 TLE,pts。
和正常 Treap 的区别是,没有使用优先级,而是每次用到优先级的时候随机一个 true/false。
回复
共 1 条回复,欢迎继续交流。
正在加载回复...