热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

树链问题的优化解法:深度优先搜索与质因数分解

本文介绍了一种通过深度优先搜索(DFS)和质因数分解来解决最长树链问题的方法。我们通过枚举树链上的最大公约数(GCD),将所有节点按其质因子分类,并计算每个类别的最长链,最终求得全局最长链。
在解决最长树链问题时,我们可以利用深度优先搜索(DFS)和质因数分解技术。具体步骤如下:

1. **枚举最大公约数(GCD)**:假设一条树链的最大公约数为gcd,那么这条树链上所有节点的权值可以表示为k * gcd,其中k是整数。
2. **质因数分类**:我们将所有节点按照其质因数进行分类。对于每个质因数p,我们可以找到所有能被p整除的节点,并对这些节点进行DFS遍历,寻找最长链。
3. **更新最长链**:每次DFS遍历后,更新当前最长链的长度。
4. **访问次数控制**:每个节点被访问的次数等于其质因子的种类数。

### 代码实现
以下是C++代码实现:

```cpp
#include
#define LL long long
#define pii pair
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;

const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const LL MOD = 998244353;

inline int read() {
int s = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) { f = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s <<1) + (s <<3) + ch - '0'; ch = getchar(); }
return s * f;
}

inline void write(int x) {
if (x <0) x = -x, putchar('-');
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}

struct Edge {
int to, next;
} edge[maxn <<2];

int cnt, head[maxn], a[maxn];
int prime[maxn], num, sum;
bool is[maxn], vis[maxn];
vector g[maxn];
map mp;

void add(int from, int to) {
edge[++cnt] = {to, head[from]};
head[from] = cnt;
}

void init() {
is[0] = is[1] = true;
for (int i = 2; i <= 1e5; ++i) {
if (!is[i]) prime[num++] = i;
for (int j = 0; i is[i * prime[j]] = true;
if (i % prime[j] == 0) break;
}
}
}

void dfs(int now, int nm) {
sum++;
vis[now] = true;
for (int i = head[now]; i; i = edge[i].next) {
int to = edge[i].to;
if (!vis[to] && a[to] % nm == 0) {
dfs(to, nm);
}
}
}

int main() {
init();
int n = read(), u, v;
for (int i = 1; i u = read(), v = read();
add(u, v), add(v, u);
}
for (int i = 1; i <= n; ++i) a[i] = read();
for (int i = 1; i <= n; ++i) {
int tmp = a[i];
for (int j = 0; j if (tmp % prime[j] == 0) {
g[prime[j]].push_back(i);
while (tmp % prime[j] == 0) tmp /= prime[j];
}
}
if (tmp > 1) {
if (tmp <= 1e5) g[tmp].push_back(i);
else mp[tmp]++;
}
}
int ans = 0;
for (auto it : mp) ans = max(ans, it.second);
for (int i = 2; i <= 1e5; ++i) {
for (auto it : g[i]) {
if (!vis[it]) {
sum = 0;
dfs(it, i);
ans = max(ans, sum);
}
}
for (auto it : g[i]) vis[it] = false;
}
write(ans);
return 0;
}
```

这种方法通过巧妙地结合DFS和质因数分解,能够高效地解决最长树链问题。
推荐阅读
  • 本文介绍如何利用栈数据结构在C++中判断字符串中的括号是否匹配。通过顺序栈和链栈两种方式实现,并详细解释了算法的核心思想和具体实现步骤。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
  • 问题描述:通过添加最少数量的括号,使得给定的括号序列变为合法,并输出最终的合法序列。数据范围:字符串长度不超过100。涉及算法:区间动态规划(Interval DP)。 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 本文详细解释了为什么在成功执行移动赋值操作后,对象的析构函数会被调用,并提供了代码示例和详细的分析。 ... [详细]
  • 本文详细介绍了如何在 Objective-C 中使用 @public 和 @protected 修饰符来控制类成员的访问权限。同时,探讨了点语法和箭头操作符的区别,以及属性声明和实现的自动生成。 ... [详细]
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • 本文详细介绍了C++中map容器的多种删除和交换操作,包括clear、erase、swap、extract和merge方法,并提供了完整的代码示例。 ... [详细]
  • 二叉树的链表实现
    本文介绍了一种使用链表结构表示二叉树的方法。通过定义节点结构和相关操作函数,可以方便地创建、插入和遍历二叉树。 ... [详细]
author-avatar
SureChueng
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有