LCT 为什么要在 splay 的时候 pushall 啊 qwq
而且如果在 splay 的时候不 pushall,只在 rotate 的时候 pushdown 会 WA,原因是什么?
这是 WA 的代码,如果把 splay 里注释掉的代码加上,那么就能过 P3690 了
#include <algorithm>
#include <cstdio>
#include <cstring>
#define L ch][0
#define R ch][1
const int N = 1e5 + 51;
int ch[N][2], s[N], v[N], r[N], p[N], st[N], top;
void up(int x) { x[s] = x[L][s] ^ x[v] ^ x[R][s]; }
void rv(int x) { std::swap(x[L], x[R]), x[r] ^= 1; }
void pd(int x) { x[r] && (rv(x[L]), rv(x[R]), x[r] = 0); }
bool nr(int x) { return x[p][L] == x || x[p][R] == x; }
bool c(int x) { return x[p][R] == x; }
void rt(int x) {
int y = x[p], z = y[p];
if (nr(y)) pd(z);
if (nr(x)) pd(y);
pd(x);
int k = c(x), w = x[ch][!k];
if (nr(y)) ch[z][c(y)] = x;
p[p[p[ch[ch[x][!k] = y][k] = w] = y] = x] = z, up(y), up(z);
}
void sp(int x) {
for (int i = st[top = 1] = x; nr(i); i = i[p]) st[++top] = i[p];
while (top) pd(st[top--]);
for (int y; y = x[p], nr(x); rt(x))
if (nr(y)) rt(c(x) == c(y) ? y : x);
up(x);
}
void ac(int x) {
for (int i = 0; x; x = (i = x)[p]) sp(x), x[R] = i, up(x);
}
void mr(int x) { ac(x), sp(x), rv(x); }
void spl(int x, int y) { mr(x), ac(y), sp(y); }
int fr(int x) {
for (ac(x), sp(x); x[L];) x = x[L];
return sp(x), x;
}
void lnk(int x, int y) {
mr(x);
if (fr(y) != x) x[p] = y;
}
void cut(int x, int y) {
mr(x);
if (fr(y) == x && y[p] == x && !y[L]) y[p] = x[R] = 0, up(x);
}
int n, m;
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", v + i);
for (int op, x, y; m--;) {
scanf("%d%d%d", &op, &x, &y);
if (!op)
spl(x, y), printf("%d\n", s[y]);
else if (op == 1)
lnk(x, y);
else if (op == 2)
cut(x, y);
else
sp(x), x[v] = y;
// for (int i = 1; i <= n; i++)
// printf("[%d %d %d %d %d]%c", i[p], i[L], i[R], i[v], i[s], " \n"[i == n]);
}
}