c++ - 高效查询路径 u 到 v
问题描述
我一直在解决一个问题,但无法找到有效的解决方案。
问题陈述:
给定一棵具有 N 个顶点和 N-1 条边的树。每个顶点 v 表示由 C[v] 给出的值,其中 C[ ] 是一个数组。对于这棵树,我们必须执行 Q 查询,如下所示:
查询由两个整数 u,v 给出。让我们定义一个值 A,它由位于 u 和 v 之间的简单路径上的所有节点的值的乘积给出。
更正式地说,如果 u 和 v 之间的简单路径是 [u,a,b...,v],那么
A = C[u] * C[a] * C[b] * ... * C[v]。
对于这个查询,我们需要输出 A 的除数数。
约束: 1<= N,Q <=100000, 1<= C[i] <=1000000 对于所有 1<= i <=N。
我的方法:由于产品可能非常大,我将主要因素及其计数存储为答案。
我首先使用二进制提升预先计算了树的 LCA。然后我为每个节点定义了一个 map< int, int >,它存储了从根到当前节点的主要除数及其乘积计数。这可以通过一个简单的 DFS 和一个用于合并地图的单独函数来实现
(注意:我正在使用O(LogN)中的筛子找到节点的素数分解)
然后对于 [u,v] 类型的每个查询,我都在寻找 LCA(比如说L)。现在我从 u 的映射中减去 L 的映射(注意:L 的映射将始终是 u 的映射的子集),对于节点 v 也是如此。
现在我有了产品的所有主要因素及其数量。
现在简单地使用结果,对于一个数字 K = a^p * b^q * c^r...,除数的数量 D = (p+1) * (q+1) * (r+1)。 ..我们得到答案。
时间复杂度分析:
让我们将 M 定义为最多 1000000 个不同的素数。
DFS 将在 O(N*M) 时间内运行:对于每个节点,在组合映射时,最坏的情况是出现所有 M 以内的素数。
LCA 预计算:O(NLogN) 时间
筛预计算:O(NLogLogN) 时间
每个查询将在 O(M+LogN) 时间内运行:O(LogN) 用于查找 LCA,O(M) 用于减去地图以找到产品的主要因素。
所以时间复杂度: O(NLogN + NM + NLogLogN + QMLogN)。
现在的问题是,在最坏的情况下,M 的数量级是 50000。所以这会增加时间复杂度。还有其他有效的方法吗?
答案必须以 1e9+7 为模报告
解决方案
推荐阅读
- flutter - Flutter - 应该只有一项具有 [DropdownButton] 的值
- mysql - 如何使用表引用获取 mysql 查询?
- javascript - 如何使图像根据文本移动?
- python - 如何在单击子窗口打开时禁用菜单按钮,直到子窗口在 tkinter 中关闭
- flutter - 在 Android Studio 的项目面板中隐藏不必要的文件夹和文件
- cookies - 嵌入 youtube 视频时的 cookie 问题
- windows - 当我在 Windows Server 下启动 HAProxy 时,出现以下错误
- android - 撰写分页:ConstraintLayout 中 NavHost 中的 LazyColumn 项方法导致 IllegalStateException:检查失败
- typescript - 无法在打字稿上正确定义函数返回类型
- visual-studio - 为什么我无法安装 Microsoft Visual Studio 安装程序项目?