[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 国际」许可协议进行许可。

posted @   purplevine  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示