我在替罪羊树上使用正常递归查询前驱后继,为什么会 TLE+MLE?(个人猜测有可能是在线时的答案错误导致的)
#include<bits/stdc++.h>
#define inf 2000000000
#define ls(x) tr[x].ls
#define rs(x) tr[x].rs
#define For(i,a,b) for(i=a;i<=b;i++)
#define FOR(i,a,b) for(i=a;i>=b;i--)
#define o1 cout<<"YES\n"
#define o0 cout<<"NO\n"
using namespace std;
const int N = 1e6 + 1e5 + 10;
struct node {
int ls, rs, key, cnt, sz, s, del;
};
struct Tzy_tree {
node tr[N];
int root, idx;
int sec[N];
double alpha = 0.7;
bool need_rebuild(int p) {
return tr[p].cnt && (alpha * tr[p].s <= (double)max(tr[ls(p)].s, tr[rs(p)].s) || (double)tr[p].del <= alpha * tr[p].s);
}
void push_up(int p) {
tr[p].s = tr[ls(p)].s + tr[rs(p)].s + 1;
tr[p].sz = tr[ls(p)].sz + tr[rs(p)].sz + tr[p].cnt;
tr[p].del = tr[ls(p)].del + tr[rs(p)].del + (tr[p].cnt != 0);
}
void Flatten(int &id, int p) {
// cout << p << '\n';
if (!p) return ;
Flatten(id, ls(p));
if (tr[p].cnt) sec[++id] = p;
Flatten(id, rs(p));
}
int Rebuild(int l, int r) {
if (l > r) return 0;
int mid = l + r >> 1;
ls(sec[mid]) = Rebuild(l, mid - 1);
rs(sec[mid]) = Rebuild(mid + 1, r);
push_up(sec[mid]);
return sec[mid];
}
void Re(int &p) {
int id = 0;
Flatten(id, p);
p = Rebuild(1, id);
}
int make_node(int key) {
tr[++idx] = {0, 0, key, 1, 1, 1, 1};
return idx;
}
void init() {
tr[++idx] = {0, 2, -inf, 1, 2, 2, 2};
tr[++idx] = {0, 0, inf, 1, 1, 1, 1};
root = 1;
}
int bad;
void insert(int &p, int key) {
if (!p) {
p = make_node(key);
return ;
}
if (key == tr[p].key) {
tr[p].cnt++;
}
else if (key < tr[p].key) {
insert(ls(p), key);
}
else {
insert(rs(p), key);
}
push_up(p);
if (need_rebuild(p)) Re(p);
// bad = p;
}
void remove(int &p, int key) {
if (key == tr[p].key) {
if (tr[p].cnt) tr[p].cnt--;
}
else if (key < tr[p].key) {
remove(ls(p), key);
}
else {
remove(rs(p), key);
}
push_up(p);
if (need_rebuild(p)) Re(p);
// bad = p;
}
void find(int &p, int key) {
if (p == bad) {
Re(p);
return ;
}
if (key == tr[p].key) return ;
if (key < tr[p].key) find(ls(p), key);
else {
find(rs(p), key);
}
}
int get_rank_by_key(int p, int key) {
if (!p) return 0;
if (key <= tr[p].key) {
return get_rank_by_key(ls(p), key);
}
return tr[ls(p)].sz + tr[p].cnt + get_rank_by_key(rs(p), key);
}
int get_key_by_rank(int p, int rank) {
if (tr[ls(p)].sz >= rank) return get_key_by_rank(ls(p), rank);
else if (tr[ls(p)].sz + tr[p].cnt >= rank) return tr[p].key;
return get_key_by_rank(rs(p), rank - tr[ls(p)].sz - tr[p].cnt);
}
int get_pre(int p, int key) {
if (!p) return -inf;
if (key <= tr[p].key) return get_pre(ls(p), key);
if (tr[p].cnt)
return max(tr[p].key, get_pre(rs(p), key));
if (tr[rs(p)].del)
return get_pre(rs(p), key);
return get_pre(ls(p), key);
}
int get_suf(int p, int key) {
if (!p) return inf;
if (key >= tr[p].key) return get_suf(rs(p), key);
if (tr[p].cnt)
return min(tr[p].key, get_suf(ls(p), key));
if (tr[ls(p)].del)
return get_suf(ls(p), key);
return get_suf(rs(p), key);
}
} tree;
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n, m;
tree.init();
cin >> n >> m;
while (n--) {
int x;
cin >> x;
tree.insert(tree.root, x);
if (tree.bad)
tree.find(tree.root, x);
tree.bad = 0;
}
int ans = 0, lastans = 0;
while (m--) {
int op, x;
cin >> op >> x;
x ^= lastans;
// cout << op << ' ' << x << '\n';
if (op == 1) {
tree.insert(tree.root, x);
if (tree.bad)
tree.find(tree.root, x);
tree.bad = 0;
}
if (op == 2) {
tree.remove(tree.root, x);
if (tree.bad)
tree.find(tree.root, x);
tree.bad = 0;
}
if (op == 3) {
lastans = tree.get_rank_by_key(tree.root, x);
ans ^= lastans;
}
if (op == 4) {
lastans = tree.get_key_by_rank(tree.root, x + 1);
ans ^= lastans;
}
if (op == 5) {
lastans = tree.get_pre(tree.root, x);
ans ^= lastans;
}
if (op == 6) {
lastans = tree.get_suf(tree.root, x);
ans ^= lastans;
}
// cout << lastans << '\n';
}
cout << ans << '\n';
return 0;
}
/*
1 106465
1 317721
1 460929
*/