社区讨论
开个O2 RE 不开就AC 人傻了
P4219[BJOI2014] 大融合参与者 4已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @locv5fm5
- 此快照首次捕获于
- 2023/10/30 20:15 2 年前
- 此快照最后确认于
- 2023/11/05 06:48 2 年前
C
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + c - '0', c = getchar();
return x * f;
}
struct LCT
{
#define ls son[pos][0]
#define rs son[pos][1]
int fa[N], sum[N], cnt[N], val[N], root, tcnt;
int son[N][2];
int exsiz[N], siz[N];
int rev[N];
void pushup(int pos)
{
siz[pos] = siz[ls] + siz[rs] + 1 + exsiz[pos];
}
bool isroot(int pos)
{
return pos != son[fa[pos]][0] && pos != son[fa[pos]][1];
}
void addtag(int pos)
{
rev[pos] ^= 1;
swap(son[pos][0], son[pos][1]);
}
void pushdown(int pos)
{
if (rev[pos])
{
if (son[pos][1])
addtag(son[pos][1]);
if (son[pos][0])
addtag(son[pos][0]);
rev[pos] = 0;
}
}
bool isson(int pos) { return pos == son[fa[pos]][1]; }
void conect(int x, int d, int y)
{
son[x][d] = y;
fa[y] = x;
}
void rorate(int x)
{
int y = fa[x], z = fa[y], dx = isson(x), dy = isson(y);
fa[x] = z;
if (!isroot(y))
son[z][dy] = x;
//conect(z, dy, x);
conect(y, dx, son[x][dx ^ 1]);
conect(x, dx ^ 1, y);
pushup(y), pushup(x);
}
int st[N];
void splay(int x)
{
int top;
st[top = 1] = x;
int u = x;
while (!isroot(u))
u = fa[u], st[++top] = u;
while (top)
pushdown(st[top--]);
while (!isroot(x))
{
int y = fa[x];
if (isroot(y))
{
rorate(x);
}
else if (isson(x) == isson(y))
rorate(y), rorate(x);
else
rorate(x), rorate(x);
}
pushup(x);
}
void access(int x)
{
for (int i = 0; x; i = x, x = fa[x])
{
splay(x);
exsiz[x] += siz[son[x][1]] - siz[i];
son[x][1] = i;
pushup(x);
}
}
void makeroot(int x)
{
access(x), splay(x), addtag(x); // access 之后将没有右子树。然后把x变成根,把下面都翻转,这样x就是最小的元素了。
}
// int findroot(int x)
// {
// access(x), splay(x);
// while (son[x][0])
// pushdown(x), x = son[x][0];
// return x;
// }
void split(int x, int y)
{
makeroot(x);
access(y);
splay(y);
}
bool link(int x, int y)
{
split(x, y);
fa[x] = y;
exsiz[y] += siz[x];
pushup(y);
}
ll query(int x, int y)
{
split(x, y);
// cout << siz[y] << " " << siz[x] << endl;
return 1ll * (siz[y] - siz[x]) * (siz[x]);
}
} t;
int main()
{
int n = read(), q = read();
while (q--)
{
char s[1];
scanf("%s", s);
int u = read(), v = read();
if (s[0] == 'A')
{
t.link(u, v);
}
else
{
printf("%lld\n", t.query(u, v));
}
}
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...