社区讨论
萌新求助LCT WA
P3203[HNOI2010] 弹飞绵羊参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @locvgb09
- 此快照首次捕获于
- 2023/10/30 20:24 2 年前
- 此快照最后确认于
- 2023/11/05 06:55 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], siz[N], cnt[N], val[N], root, tcnt;
int son[N][2];
int rev[N];
void pushup(int pos)
{
siz[pos] = val[pos] + siz[ls] + siz[rs];
}
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), 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];
// splay(x);
// return x;
// }
void split(int x, int y)
{
makeroot(x);
access(y);
splay(y);
}
bool link(int x, int y)
{
// cout << x << " " << y << endl;
makeroot(x);
// if (findroot(y) == x)
// return 0; //两点已经在同一子树中,再连边不合法
fa[x] = y;
return 1;
}
bool cut(int x, int y)
{
split(x, y);
fa[x] = son[y][0] = 0;
pushup(y);
return 1;
}
} t;
int a[N];
int main()
{
// freopen("1.in", "r", stdin);
// freopen("1.out", "w", stdout);
int n = read();
for (int i = 1; i <= n; i++)
{
t.val[i] = 1;
a[i] = read();
if (i + a[i] <= n)
t.link(i, i + a[i]);
}
int m = read();
for (int i = 1; i <= m; i++)
{
int op = read(), x = read();
x++;
//cout << i << "--" << endl;
if (op == 1)
{
t.makeroot(x);
printf("%d\n", t.siz[x]);
}
else
{
int k = read();
if (x + a[x] <= n)
t.cut(x, x + a[x]);
a[x] = k;
if (x + a[x] <= n)
t.link(x, x + a[x]);
}
}
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...