题解 P6018 [Ynoi2010] Fusion tree

发现每个点距离为 1 的节点就是儿子或者父亲,因此可以把儿子和父亲分开来算。

计算父亲是很容易的,直接维护 a 的值。对于操作 1 ,在父亲上标记就行了,表示这个点进行过几次的操作 1

对于每个节点维护儿子,就会发现是要维护:单点加入、单点删除、全局 +1,全局异或和。

如果对 01-trie 比较熟悉,可以发现 01-trie 可以维护这个东西。从低位到高位建立 01-trie,大致是要维护每个节点的子树的异或和 val,还有每个节点到父亲的边权 w(指这条边被经过了几次)。

由于是异或,会发现可以只考虑 w 的奇偶性。于是 push_up 大致是这样的:

inline void push_up(int u)
{
	w[u]=0,val[u]=0;
	if (nxt[u][0])
	{
		w[u]^=w[nxt[u][0]];
		val[u]^=(val[nxt[u][0]]<<1);
	}
	if (nxt[u][1])
	{
		w[u]^=w[nxt[u][1]];
		val[u]^=(val[nxt[u][1]]<<1);
		if (w[nxt[u][1]]==1) val[u]^=1;
	}
}

注意到只考虑 w 的奇偶性,因此 insert 和 delete 本质相同。你可以理解为,先加入一个数 x,要把它删除等同于再加一个 x,这样异或和为 0 了。所以其实没有必要写两个函数(但是好像基本上题解都写了)。

如何处理全局 +1?从低到高考虑,每一位 1 变成 0 同时进位,0 变成 1 不进位。递归做就行了。

void add(int x)
{
	swap(nxt[x][0],nxt[x][1]);
	if (nxt[x][0]) add(nxt[x][0]);
	push_up(x);
}

于是就可以维护了。注意一些实现的细节。

提交记录代码实现

posted @   Little09  阅读(49)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示