替罪羊树
暴力重构的思想,如果树不够平衡,那么就拍扁重构即可
和 treap 的操作大致都一样就是了,但常数挺小的,可以卡常使用
const int N = 2005000;
struct node {
int ls, rs, siz, sum;
int key, val;
#define key(k) p[k].key
#define val(k) p[k].val
#define ls(k) p[k].ls
#define rs(k) p[k].rs
#define siz(k) p[k].siz
#define sum(k) p[k].sum
}p[N];
int rt, cnt;
const double A = 0.8;
bool judge(int k) {
return val(k) && A * siz(k) < max(siz(ls(k)), siz(rs(k)));
}
void update(int k) {
siz(k) = siz(ls(k)) + siz(rs(k)) + (val(k) ? 1 : 0);
sum(k) = sum(ls(k)) + sum(rs(k)) + val(k);
}
int st[N], tp;
void pia(int k) {
if (ls(k)) pia(ls(k));
if (val(k)) st[++tp] = k;
if (rs(k)) pia(rs(k));
return;
}
int rebuild(int l, int r) {
if (l > r) return 0;
int mid = (l + r) >> 1;
ls(st[mid]) = rebuild(l, mid - 1);
rs(st[mid]) = rebuild(mid + 1, r);
return update(st[mid]), st[mid];
}
int maintain(int p) {
return tp = 0, pia(p), rebuild(1, tp);
}
void insert(int &x, int val) {
if (!x) {
x = ++cnt, key(x) = val;
val(x) = siz(x) = sum(x) = 1;
}
else {
if (key(x) == val) val(x)++;
else if (val < key(x)) insert(ls(x), val);
else insert(rs(x), val);
update(x); judge(x) && (x = maintain(x));
}
}
void del(int &x, int val) {
sum(x)--;
if (key(x) == val) val(x)--;
else key(x) > val ? del(ls(x), val) : del(rs(x), val);
update(x), judge(x) && (x = maintain(x));
}
int rkup(int x, int k) {
int nw = 0;
while (1) {
if (!x) return nw;
if (key(x) == k) return nw + sum(ls(x)) + val(x);
if (key(x) <= k) nw += sum(ls(x)) + val(x), x = rs(x);
else x = ls(x);
}
}
int rkdw(int x, int k) {
int nw = 1;
while (1) {
if (!x) return nw;
if (key(x) == k) return nw + sum(ls(x));
if (key(x) <= k) nw += sum(ls(x)) + val(x), x = rs(x);
else x = ls(x);
}
}
int get(int k) {
int x = rt;
while (1) {
if (sum(ls(x)) >= k) x = ls(x);
else if (sum(ls(x)) + val(x) >= k) return key(x);
else k -= sum(ls(x)) + val(x), x = rs(x);
}
return 1;
}
int n, t, x, m, las, ans;
int main() {
for (read(n), read(m); n; n--)
read(x), insert(rt, x);
for (; m; m--) {
read(t), read(x), x ^= las;
if (t == 1) insert(rt, x);
else if (t == 2) del(rt, x);
else if (t == 3) las = rkdw(rt, x);
else if (t == 4) las = get(x);
else if (t == 5) las = get(rkdw(rt, x) - 1);
else las = get(rkup(rt, x) + 1);
if (t >= 3) ans ^= las;
}
write(ans);
return 0;
}