TernaryTree @ 2024-01-31 10:07:12
#include <bits/stdc++.h>
//#define int long long
#define ls ch[0]
#define rs ch[1]
using namespace std;
using db = double;
struct ios {
inline char read() {
static const int inlen = 1 << 18 | 1;
static char buf[inlen], *s, *t;
return (s == t) && (t = (s = buf) + fread(buf, 1, inlen, stdin)), s == t ? -1 : *s++;
}
template<typename T> inline ios& operator>> (T &x) {
static char c11, boo;
for (c11 = read(), boo = 0; !isdigit(c11); c11 = read()) {
if (c11 == -1) return *this;
boo |= c11 == '-';
}
for (x = 0; isdigit(c11); c11 = read()) x = x * 10 + (c11 ^ '0');
boo && (x = -x);
return *this;
}
} fin;
struct exios {
template<typename _CharT, typename _Traits = char_traits<_CharT>>
struct typ {
typedef basic_ostream<_CharT, _Traits>& (* end) (basic_ostream<_CharT, _Traits>&);
};
template<typename T> friend exios &operator<<(exios &out, T num) {
if (num < 0) putchar('-'), num = -num;
if (num >= 10) out << num / 10;
putchar(num % 10 + '0');
return out;
}
friend exios &operator<<(exios &out, const char * s) { printf("%s", s); return out; }
friend exios &operator<<(exios &out, string s) { cout << s; return out; }
friend exios &operator<<(exios &out, typ<char>::end e) { puts(""); return out; }
} fout;
const int maxn = 2.3e6 + 10;
const db A = 1 - sqrt(2) / 2;
struct node {
int l, r, size;
int ch[2] = {};
};
node tr[maxn];
int root, tot, cnt;
int del[maxn];
int newnode(int x) {
tr[++tot].l = x;
tr[tot].r = x;
tr[tot].size = 1;
return tot;
}
void pushup(int u) {
if (tr[u].ls) {
tr[u].size = tr[tr[u].ls].size + tr[tr[u].rs].size;
if (tr[u].size == cnt) root = u;
tr[u].l = min(tr[tr[u].ls].l, tr[tr[u].rs].l);
tr[u].r = max(tr[tr[u].ls].r, tr[tr[u].rs].r);
}
}
void rotate(int u, int d) {
int tmp = tr[u].ch[d ^ 1];
tr[u].ch[d ^ 1] = tr[u].ch[d];
tr[u].ch[d] = tr[tr[u].ch[d ^ 1]].ch[d];
tr[tr[u].ch[d ^ 1]].ch[d] = tr[tr[u].ch[d ^ 1]].ch[d ^ 1];
tr[tr[u].ch[d ^ 1]].ch[d ^ 1] = tmp;
pushup(tr[u].ch[d ^ 1]);
pushup(u);
}
void maintain(int u) {
int d;
if (tr[u].ls) {
if (tr[tr[u].ls].size < tr[u].size * A) d = 1;
else if (tr[tr[u].rs].size < tr[u].size * A) d = 0;
else return;
}
if (tr[tr[tr[u].ch[d]].ch[d ^ 1]].size >= tr[tr[u].ch[d]].size * ((1 - A * 2) / (1 - A))) rotate(tr[u].ch[d], d ^ 1);
else rotate(u, d);
}
void insert(int u, int x) {
if (!cnt) return (void) (newnode(x), ++cnt, root = tot);
if (tr[u].size == 1) {
tr[u].ls = newnode(x);
tr[u].rs = newnode(tr[u].l);
++cnt;
if (x > tr[u].l) swap(tr[u].ls, tr[u].rs);
} else {
insert(tr[u].ch[x > tr[tr[u].ls].r], x);
}
pushup(u);
maintain(u);
}
void delnode(int u) {
tr[u].ls = tr[u].rs = tr[u].l = tr[u].r = tr[u].size = 0;
del[u] = 1;
}
void remove(int u, int x) {
if (cnt == 1) return (void) (delnode(u), --cnt, root = 0);
int d = x > tr[tr[u].ls].r;
if (tr[tr[u].ch[d]].size == 1) {
if (tr[tr[u].ch[d]].l != x) return;
delnode(tr[u].ch[d]);
int tmp = tr[u].ch[d ^ 1];
tr[u] = tr[tr[u].ch[d ^ 1]];
delnode(tmp);
cnt--;
} else {
remove(tr[u].ch[d], x);
}
pushup(u);
maintain(u);
}
int queryrank(int u, int x) {
if (tr[u].size == 1) return (tr[u].l < x) + 1;
if (x > tr[tr[u].ls].r) return tr[tr[u].ls].size + queryrank(tr[u].rs, x);
else return queryrank(tr[u].ls, x);
}
int getkth(int u, int k) {
if (tr[u].size == 1) return tr[u].l;
if (k <= tr[tr[u].ls].size) return getkth(tr[u].ls, k);
else return getkth(tr[u].rs, k - tr[tr[u].ls].size);
}
int getpre(int u, int x) {
if (tr[u].size == 1) return tr[u].l;
if (x <= tr[tr[u].rs].l) return getpre(tr[u].ls, x);
else return getpre(tr[u].rs, x);
}
int getsuf(int u, int x) {
if (tr[u].size == 1) return tr[u].l;
if (x >= tr[tr[u].ls].r) return getsuf(tr[u].rs, x);
else return getsuf(tr[u].ls, x);
}
void debug() {
cout << root << endl;
for (int i = 1; i <= tot; i++) {
cout << tr[i].ls << " " << tr[i].rs << " " << tr[i].l << " " << tr[i].r << " " << tr[i].size << " " << del[i] << endl;
}
}
signed main() {
int n, m, last = 0, ans = 0;
fin >> n >> m;
while (n--) {
int x;
fin >> x;
insert(root, x);
}
while (m--) {
int op, x;
fin >> op >> x;
x ^= last;
if (op == 1) insert(root, x);
else if (op == 2) remove(root, x);
else if (op == 3) (last = queryrank(root, x));
else if (op == 4) (last = getkth(root, x));
else if (op == 5) (last = getpre(root, x));
else if (op == 6) (last = getsuf(root, x));
if (op >= 3 && op <= 6) ans ^= last;
}
fout << ans << endl;
return 0;
}
by Meardoe @ 2024-01-31 10:12:16
你咋在写网暴了树?
by TernaryTree @ 2024-01-31 10:14:18
@Meardoe ?
by call_of_silence @ 2024-01-31 10:22:09
@TernaryTree 3.2s固若磐石,时间充裕的话建议重构ing
by TernaryTree @ 2024-01-31 10:23:02
@call_of_silence 我发现是 RE,/ng。
by TernaryTree @ 2024-01-31 10:56:48
@call_of_silence 哥们,我会 fhq
by call_of_silence @ 2024-01-31 10:59:04
@TernaryTree orz,大佬加油
by TernaryTree @ 2024-01-31 11:33:55
已通过,感谢。