[ds记录]P3203 弹飞绵羊
一道简单好玩的题,可以加深对 LCT 的理解。
题意简述:给定一座森林,支持两个操作:把某个节点的父亲改成另一个节点、查询某个节点到其对应树树根的距离。
看到有动态连边断边就可以先想 LCT。
LCT 的特点是长于处理序列信息。对于这种查询到根的路径,不用换根,只需 access 后直接查询 Splay 即可。
至于断边,也可以理解为把 x 分离出这个 splay。只需在 splay(x)
后双向断开 x 与其左儿子即可。
连边直接连虚边,因为认父不认子,只需改一次 fa 即可。因为 x 的子树有改变,记得 pushup(x)
。
题不难,带来的对 LCT 的启发有:
- 一般连边只用连虚边,能保证 LCT 性质即可。
- 改虚实边仅会通过 access 操作,在普通处理时 access 后仅考虑当前节点所在 splay 即可。所有通过虚边连向 x 的节点的相对位置也会改变,即把 x 连其子树一起换到了其它位置。
access 是 LCT 的所有操作的基础。此题仅使用 access 操作就可解决。
//time : 2022-06-19
//problem url : https://www.luogu.com.cn/problem/P3203
//status : AC
#include <cstdio>
#include <queue>
#define inf 10000005
using namespace std;
const int M = 200005;
int op, x, n, m, y, a[M], k[M];
struct LCT{
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
#define isroot(x) (ch[fa[x]][0] != x && ch[fa[x]][1] != x)
int sz[M], rt, tot, fa[M], ch[M][2];
void pushup(int x) {sz[x] = sz[ls(x)] + sz[rs(x)] + 1;}
bool get(int x) {return x == rs(fa[x]);}
void rotate(int x){
int y = fa[x], z = fa[y], chk = get(x);
if (!isroot(y)) ch[z][ch[z][1] == y] = x;
ch[y][chk] = ch[x][chk ^ 1]; if(ch[x][chk ^ 1]) fa[ch[x][chk ^ 1]] = y;
fa[y] = x; ch[x][chk ^ 1] = y; fa[x] = z;
pushup(y); pushup(x);
}
void splay(int x){
while(!isroot(x)){
int y = fa[x];
if(!isroot(y)) rotate(get(x) == get(y) ? y : x);
rotate(x);
}
}
void access(int x){
int f = x;
for(int y = 0; x; y = x, x = fa[x]){
splay(x); rs(x) = y; pushup(x);
}
splay(f);
}
void modify(int x, int y){
access(x); splay(x); fa[ch[x][0]] = 0; ch[x][0] = 0;
if(x + y <= n) fa[x] = x+y; pushup(x);
}
int query(int x){
access(x); splay(x); return sz[x];
}
}T;
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &k[i]);
if(i + k[i] <= n) T.fa[i] = i + k[i];
}
scanf("%d", &m);
while(m--){
scanf("%d %d", &op, &x); ++x;
if(op == 1) printf("%d\n", T.query(x));
else scanf("%d", &y), T.modify(x, y);
}
}
作者:purplevine
出处:https://www.cnblogs.com/purplevine/p/16398303.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
本文来自博客园,作者:purplevine,转载请注明原文链接:https://www.cnblogs.com/purplevine/p/16398303.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!