2025“钉耙编程”中国大学生算法设计春季联赛(4)1004 充实

news/2025/3/31 5:00:18/文章来源:https://www.cnblogs.com/archer233/p/18799081

题目大意

小 hua 用一棵树模型描述自己的竞赛生涯,树上的每条从根到叶子的路径代表一个“支线”。每个节点有一个点权 $ a_i $,且越往下的节点点权越大(构成小根堆)。对于每条“支线”,我们需要判断它是否是充实的。具体来说:

  • 将路径上的点权放入集合 $ S $。
  • 每次可以从 $ S $ 中选择两个奇偶性相同的数 $ x, y $,并将 $ \frac{x + y}{2} $ 放入 $ S $,重复此操作若干次。
  • 如果最终 $ S $ 能够覆盖从 $ \min(S) $ 到 $ \max(S) $ 的完整值域,则该路径是充实的。

给定树的结构和点权,求有多少条从根到叶子的路径是充实的。


解题思路

核心思想:差分数组与最大公约数 (GCD)

通过分析题目条件,可以将问题转化为对路径上点权的差分数组进行性质判断。以下是解题的关键步骤:


1. 差分数组的性质

对于一条路径上的点权序列 $ a_1, a_2, \dots, a_k $,我们定义其差分数组为:

\[d_i = a_{i+1} - a_i \quad (i = 1, 2, \dots, k-1) \]

观察题目中的操作规则,可以发现以下性质:

  1. 操作的本质

    • 每次操作 $ \frac{x + y}{2} $ 实际上是对差分数组中某些元素进行约简。
    • 具体来说,如果差分数组中有偶数,可以通过不断除以 2 进行约简。
  2. 合法路径的充要条件

    • 差分数组的所有元素的最大公约数 $ \gcd(d_1, d_2, \dots, d_{k-1}) $ 必须是 2 的幂次形式(即 $ \gcd(d_1, d_2, \dots, d_{k-1}) = 2^t $,其中 $ t \geq 0 $)。

因此,判断一条路径是否充实,只需计算其差分数组的 GCD 是否满足上述条件。


2. DFS 过程中动态维护 GCD

为了高效地统计所有路径的结果,我们可以使用深度优先搜索 (DFS) 在树上遍历:

  • 从根节点开始,沿着每条路径递归向下。
  • 在递归过程中,动态维护当前路径的差分数组的 GCD。
  • 当到达叶子节点时,检查当前路径的 GCD 是否为 2 的幂次形式,若是则计入答案。

这种方法的时间复杂度为 $ O(n \log a) $,其中 $ n $ 是树的节点数,$ \log a $ 是计算 GCD 的复杂度。


3. 特殊边界处理

在实现过程中需要注意以下细节:

  • 树的根节点只有一个点权 $ a_1 $,没有差分值。
  • 对于单节点路径(即只有一个点),直接判定为不充实。
  • GCD 的初始值设置为 0,表示尚未开始计算。

代码实现

以下是完整的代码实现:

#include<bits/stdc++.h>
#define int long long
using namespace std;const int N = 1e5 + 10;void solve() {int n; cin >> n;vector<vector<int>> G(n + 1); // 邻接表存储树for (int i = 2; i <= n; i++) {int fa; cin >> fa;G[fa].push_back(i);}vector<int> a(n + 1); // 点权for (int i = 1; i <= n; i++) cin >> a[i];int cnt = 0; // 记录充实路径的数量// 定义 DFS 函数function<void(int, int)> dfs = [&](int u, int gc) {if (G[u].empty()) { // 叶子节点if (gc == 0 || (gc & (gc - 1)) == 0) cnt++; // 判断 gcd 是否为 2 的幂次return;}for (auto v : G[u]) {dfs(v, __gcd(gc, a[v] - a[u])); // 动态维护 GCD}};dfs(1, 0); // 从根节点开始 DFScout << cnt << '\n';
}signed main() {ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);int T; cin >> T;while (T--) solve();
}

代码解析

1. 输入与建图

  • 使用邻接表 G 存储树的结构。
  • 输入点权数组 a,并保证 $ a_{f_i} \leq a_i $。

2. DFS 函数

  • 参数说明:
    • u:当前节点编号。
    • gc:当前路径的差分数组的 GCD。
  • 递归过程:
    • 如果当前节点是叶子节点,检查 GCD 是否为 2 的幂次形式。
    • 否则,递归访问子节点,并更新 GCD。

3. 边界条件

  • 单节点路径直接判定为不充实。
  • GCD 初始值为 0,表示尚未开始计算。

时间复杂度

算法的时间复杂度为:

\[O(T \cdot n \cdot \log a) \]

其中:

  • $ T $ 是测试数据组数。
  • $ n $ 是树的节点数。
  • $ \log a $ 是计算 GCD 的复杂度。

对于 $ n \leq 10^5 $ 和 $ a \leq 10^9 $,该算法可以轻松通过所有测试数据。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/907440.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

洛谷 P1216 [IOI 1994] 数字三角形 Number Triangles (记忆化搜索)

记忆化搜索思路:经典的DP题,看题解大佬个个是状态转移方程...我就写个记忆化搜索吧,这个数据量,只dfs暴搜是过不去的,写完记忆化之后发现有个测试点T了,下载了一波测试点数据,发现全是0,那么初始化dp数组为-1就好了。AcCode: #include<bits/stdc++.h> using nam…

【软件】在Windows和Ubuntu上使用TFTP和NFS

在Windows和Ubuntu上使用TFTP和NFS 零、介绍 最近在玩Linux开发板,在开发的过程中发现需要用到tftp和nfs来帮助传输文件,故此记录如何使用这两种软件。 TFTP(Trivial File Transfer Protocol) :是一种简化的文件传输协议,设计用于在客户端和服务器之间快速传输文件。轻量…

FastAPI Pydantic动态调整Schema

title: FastAPI Pydantic动态调整Schema date: 2025/3/29 updated: 2025/3/29 author: cmdragon excerpt: Pydantic动态Schema支持运行时字段调整和环境变量控制,实现毫秒级配置生效。通过字段级动态注入和条件必填验证,灵活适应业务需求。多租户系统采用条件字段过滤实现数…

【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(4)

比赛链接 本文发布于博客园,会跟随补题进度实时更新,若您在其他平台阅读到此文,请前往博客园获取更好的阅读体验。 跳转链接:https://www.cnblogs.com/TianTianChaoFangDe/p/18799072 开题 + 补题情况 和前三场比起来前期的签到题发挥稳定了许多,没有被卡很久,不过 1001 …

详细介绍Mybatis的缓存机制

一、缓存机制 1、缓存概述 缓存:缓存就是一块内存空间,保存临时数据 作用:将数据源(数据库或者文件)中的数据读取出来存放到缓存中,再次获取时直接从缓存中获取,可以减少和数据库交互的次数,提升程序的性能 缓存适用: 适用于缓存的:经常查询但不经常修改的,数据的正…

JS梳理之es6异步async await 协程 迭代器

es6异步 promise 链式调用 是对回调炼狱的一种优化 这次梳理一下async await async function fetchData() {const response = await fetch(https://api.example.com/data);const data = await response.json();return data; }// async 声明这是一个异步函数 // await 会暂停函数…

百度云同步盘 登录失败【%d】【155010】

前言全局说明百度云同步盘在2016前后升级了一次,修改了接口,但是没有发布完整安装包,当时可以自动升级来解决,后来自动升级失效,就之能手动打补丁来解决了。详细解决过程:https://www.cnblogs.com/wutou/p/18799043一、说明 1.1 环境: Windows 11 家庭版 23H2 22631.3737二…

grpc实现Aop

创建项目服务端:微软官方自带的ASP.NET.Core.gRPC服务项目。 客户端:ASP.NET.Core.WebApi项目。 公共类库:主要为AOP自定义拦截器类。依赖包导入 客户端:Grpc.AspNetCore、Grpc.Core.Api、Grpc.Net.ClientFactory、Grpc.Tools。公共类库:Grpc.Core.Api公共类库项目配置 创…

Win 11 安装百度云同步盘

前言全局说明百度网盘最早出来叫“百度云管家”,可以上传下载东西,后来大概在2012年,百度云同步盘上线,后来将云管家和同步盘放到一起,叫百度云,也就是现在用的这个。下面介绍 如何在 Win11上用百度云同步盘一、说明 1.1 环境: Windows 11 家庭版 23H2 22631.3737二、下载…

C语言打卡学习第7天(2025.3.26)(补发)

![](https://img2024.cnblogs.com/blog/3622651/202503/3622651- 20250329002951976-79699626.jpg)1.换个网站把题简单做了几道 2,把积存的问题好好问了一下,明天“亡羊补牢”:冒泡排序、数组指针简单用法、之前网站的简单题 明天贪一点,起码把原来网站那些题啃了

VGG

VGG 网络LRN(Local Response Normalization)来自于AlexNet现在已经不怎么使用,因为经过很多实验并没有较大的作用 conv的stride为1,padding为1 maxpool的size为2,stride为2感受野叠加 论文中一个比较重要的使用就是感受野的叠加 感受野(Receptive Field)是卷积神经网络中一…

日语声调

日语声调的记忆 方法1方法2方法3日语声调的标记方法 方法1:划线规律1:第1个音 和 第2个音不是同音 规律2:出现降音就不会升回去 规律3:“高-低”在第几个音出现,就是几型 方法2:数字