2018-ACetic_ACid/LCT
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include <bits/stdc++.h>
#define N 100010
using namespace std;
int fa[N], c[2][N], si[N], sum[N], rev[N], val[N];
void pushup(int x)
{
sum[x] = sum[c[0][x]] + sum[c[1][x]] + si[x] + val[x];
}
void pushdown(int x)
{
if (rev[x])
{
int l = c[0][x], r = c[1][x];
swap(c[0][l], c[1][l]), swap(c[0][r], c[1][r]);
rev[l] ^= 1, rev[r] ^= 1, rev[x] = 0;
}
}
bool isroot(int x)
{
return c[0][fa[x]] != x && c[1][fa[x]] != x;
}
void update(int x)
{
if (!isroot(x))
update(fa[x]);
pushdown(x);
}
void rotate(int x)
{
int y = fa[x], z = fa[y], l = (c[1][y] == x), r = l ^ 1;
if (!isroot(y))
c[c[1][z] == y][z] = x;
fa[x] = z, fa[y] = x, fa[c[r][x]] = y, c[l][y] = c[r][x], c[r][x] = y;
pushup(y), pushup(x);
}
void splay(int x)
{
update(x);
while (!isroot(x))
{
int y = fa[x], z = fa[y];
if (!isroot(y))
{
if ((c[0][y] == x) ^ (c[0][z] == y))
rotate(x);
else
rotate(y);
}
rotate(x);
}
}
void access(int x)
{
int t = 0;
while (x)
splay(x), si[x] += sum[c[1][x]] - sum[t], c[1][x] = t, pushup(x), t = x, x = fa[x];
}
void makeroot(int x)
{
access(x), splay(x), swap(c[0][x], c[1][x]), rev[x] = 1;
}
void split(int x, int y)
{
makeroot(x), makeroot(y);
}
void link(int x, int y)
{
split(x, y), fa[x] = y, si[y] += sum[x], pushup(y);
}
void cut(int x, int y)
{
makeroot(x), access(y), splay(y), c[0][y] = fa[x] = 0, pushup(y);
}
int findroot(int x)
{
access(x); splay(x);
pushdown(x);
while (c[0][x]) pushdown(x = c[0][x]);
return x;
}
int findfa(int x)
{
access(x); splay(x);
pushdown(x);
int t = c[0][x];
pushdown(t);
while (c[1][t]) pushdown(t = c[1][t]);
return t;
}
}}}
#include <bits/stdc++.h>
#define N 100010
using namespace std;
int fa[N], c[2][N], si[N], sum[N], rev[N], val[N];
void pushup(int x)
{
sum[x] = sum[c[0][x]] + sum[c[1][x]] + si[x] + val[x];
}
void pushdown(int x)
{
if (rev[x])
{
int l = c[0][x], r = c[1][x];
swap(c[0][l], c[1][l]), swap(c[0][r], c[1][r]);
rev[l] ^= 1, rev[r] ^= 1, rev[x] = 0;
}
}
bool isroot(int x)
{
return c[0][fa[x]] != x && c[1][fa[x]] != x;
}
void update(int x)
{
if (!isroot(x))
update(fa[x]);
pushdown(x);
}
void rotate(int x)
{
int y = fa[x], z = fa[y], l = (c[1][y] == x), r = l ^ 1;
if (!isroot(y))
c[c[1][z] == y][z] = x;
fa[x] = z, fa[y] = x, fa[c[r][x]] = y, c[l][y] = c[r][x], c[r][x] = y;
pushup(y), pushup(x);
}
void splay(int x)
{
update(x);
while (!isroot(x))
{
int y = fa[x], z = fa[y];
if (!isroot(y))
{
if ((c[0][y] == x) ^ (c[0][z] == y))
rotate(x);
else
rotate(y);
}
rotate(x);
}
}
void access(int x)
{
int t = 0;
while (x)
splay(x), si[x] += sum[c[1][x]] - sum[t], c[1][x] = t, pushup(x), t = x, x = fa[x];
}
void makeroot(int x)
{
access(x), splay(x), swap(c[0][x], c[1][x]), rev[x] = 1;
}
void split(int x, int y)
{
makeroot(x), makeroot(y);
}
void link(int x, int y)
{
split(x, y), fa[x] = y, si[y] += sum[x], pushup(y);
}
void cut(int x, int y)
{
makeroot(x), access(y), splay(y), c[0][y] = fa[x] = 0, pushup(y);
}
int findroot(int x)
{
access(x); splay(x);
pushdown(x);
while (c[0][x]) pushdown(x = c[0][x]);
return x;
}
int findfa(int x)
{
access(x); splay(x);
pushdown(x);
int t = c[0][x];
pushdown(t);
while (c[1][t]) pushdown(t = c[1][t]);
return t;
}