rt,本题我在用 lct 写的时候发现,如果将 makeroot 函数中的 rev[x] ^= 1 改成 rev[x] = 1 也能通过。
而且其他题目(P3366、P2417、P1501等)也行,这是数据太水了还是某种玄学因素?
(附:我的 lct 代码)
struct LCT{
int ch[_N][2], fa[_N], sz[_N], rev[_N];
#define ls ch[x][0]
#define rs ch[x][1]
#define get(x) (x == ch[find(fa[x])][1])
#define isRoot(x) (ch[find(fa[x])][0] != x && ch[find(fa[x])][1] != x)
void maintain(int x) { sz[0] = 0, sz[x] = sz[ls] + sz[rs] + 1; }
void pushdown(int x) {
if (rev[x]) {
rev[ls] ^= 1, rev[rs] ^= 1;
swap(ch[ls][0], ch[ls][1]);
swap(ch[rs][0], ch[rs][1]);
rev[x] = 0;
}
}
void update(int x) {
if (!isRoot(x)) update(find(fa[x]));
pushdown(x);
}
void rotate(int x) {
x = find(x);
int y = find(fa[x]), z = find(fa[y]), tp = get(x);
if (!isRoot(y)) ch[z][get(y)] = x;
fa[x] = z;
ch[y][tp] = ch[x][tp ^ 1];
if (ch[x][tp ^ 1]) fa[ch[x][tp ^ 1]] = y;
ch[x][tp ^ 1] = y;
fa[y] = x;
maintain(y);
maintain(x);
}
void splay(int x) {
x = find(x);
update(x);
while (!isRoot(x)) {
int y = fa[x];
if (!isRoot(y)) rotate(get(x) == get(y) ? y : x);
rotate(x);
}
}
void access(int x) {
for (int p = 0; x; x = find(fa[p = x])) {
splay(x);
ch[x][1] = p;
maintain(x);
}
}
void makeRoot(int x) {
x = find(x);
access(x);
splay(x);
rev[x] = 1;
swap(ls, rs);
}
int findRoot(int x) {
x = find(x);
access(x);
splay(x);
pushdown(x);
while (ls) pushdown(x), x = ls;
splay(x);
return x;
}
void split(int x, int y) {
makeRoot(x);
access(y);
splay(y);
}
void subtree(int x) {
pushdown(x);
if (ls) subtree(ls), merge(x, ls);
if (rs) subtree(rs), merge(x, rs);
}
void link(int x, int y) {
makeRoot(x);
splay(x);
fa[x] = y;
}
}lct;```