Kevin_Zhen @ 2021-06-29 18:29:27
只过了 #3 和 #4,而且不知道为什么范围
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 2e6 + 10;
const int inf = 0x3f3f3f3f;
int n, m, rt, tot, lst, ans;
int val[maxn], ch[maxn][2], fa[maxn];
int cnt[maxn], siz[maxn];
inline void update(int u) { siz[u] = siz[ch[u][0]] + siz[ch[u][1]] + cnt[u]; }
inline int newnode(int x) {
val[++tot] = x;
cnt[tot] = siz[tot] = 1;
fa[tot] = ch[tot][0] = ch[tot][1] = 0;
return tot;
}
inline void init() {
tot = 0;
newnode(-inf); newnode(inf);
rt = 1; siz[1] = 2;
ch[1][1] = 2; fa[2] = 1;
}
inline void rotate(int u) {
int f = fa[u], gf = fa[f], k = (ch[f][1] == u);
ch[f][k] = ch[u][k ^ 1]; fa[ch[u][k ^ 1]] = f;
ch[u][k ^ 1] = f; fa[f] = u;
ch[gf][ch[gf][1] == f] = u; fa[u] = gf;
update(f); update(u);
}
inline void splay(int u, int goal = 0) {
if (!goal) rt = u;
while (fa[u] != goal) {
int f = fa[u], gf = fa[f];
if (gf != goal) (ch[f][1] == u) ^ (ch[gf][1] == f) ? rotate(u) : rotate(f);
rotate(u);
}
}
inline void find(int x) {
int p = rt;
while (val[p] != x && ch[p][x > val[p]]) p = ch[p][x > val[p]];
splay(p);
}
inline int pre(int x) {//找的是结点编号
find(x);
if (val[rt] < x) return rt;
int p = ch[rt][0];
while (ch[p][1]) p = ch[p][1];
return splay(p), p;
}
inline int suc(int x) {//号
find(x);
if (val[rt] > x) return rt;
int p = ch[rt][1];
while (ch[p][0]) p = ch[p][0];
return splay(p), p;
}
inline int kth(int k) {//号
int p = rt;
while (1) {
int v = ch[p][0];
if (siz[v] + cnt[p] < k) k -= siz[v] + cnt[p], p = ch[p][1];
else {
if (siz[v] < k) return splay(p), p;
else p = v;
}
}
}
inline void ins(int x) {
int p = rt, f = 0;
while (p && val[p] != x) f = p, p = ch[p][x > val[p]];
if (!p) {
p = newnode(x);
ch[f][x > val[f]] = p;
fa[p] = f;
} else ++cnt[p];
splay(p);
}
inline void del(int x) {
int xp = pre(x), xs = suc(x);
splay(xp); splay(xs, xp);
int p = ch[xs][0];
if (--cnt[p]) splay(p);
else ch[xs][0] = 0, update(xs), update(xp);
}
inline int rk(int x) {
ins(x); find(x);
int res = siz[ch[rt][0]] + 1;
return del(x), res;
}
int main() {
init();
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
int t; scanf("%d", &t);
ins(t);
}
while (m--) {
int opt, x; scanf("%d%d", &opt, &x); x ^= lst;
if (opt == 1) ins(x);
else if (opt == 2) del(x);
else if (opt == 3) ans ^= lst = rk(x) - 1;
else if (opt == 4) ans ^= lst = val[kth(x + 1)];
else if (opt == 5) ans ^= lst = val[pre(x)];
else if (opt == 6) ans ^= lst = val[suc(x)];
}
printf("%d", ans);
return 0;
}
by Kevin_Zhen @ 2021-06-30 22:37:52
完结咯,告诫后人:
by Kevin_Zhen @ 2021-06-30 22:39:06
另外,
by lcyxds @ 2021-07-04 20:59:40
@九章 ?偶然发现你的代码交上去改成spaly居然所有点都更快
by Kevin_Zhen @ 2021-07-05 21:45:09
@lcyxds 害怕!可能是因为 spaly 是信仰( /jk