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

2019西安邀请赛J题解析:树形动态规划求解异或路径问题

本文详细解析了2019年西安邀请赛中的一道树形动态规划题目——J题《AndAndAnd》。题目要求计算树中所有子路径异或值为0的集合数量,通过深入分析和算法优化,提供了高效的解决方案。

题目背景与链接

本题源自2019年西安邀请赛,题目编号为J。题目要求在给定的一棵树中,找到所有子路径的集合,使得这些子路径的异或值为0。

问题分析:

若仅需计算异或值为0的路径数量,则此问题相对简单。但本题进一步要求计算满足条件的路径集合的数量,这需要我们从基础问题出发进行扩展思考。具体来说,我们需要计算的是树中所有可能的子路径中,哪些子路径的异或值为0。这本质上是一个计数问题,利用异或运算的一个重要性质,即任何数字与自身异或的结果为0(x^x=0),可以帮助我们设计算法。

设1为树的根节点,定义xor[i]表示从节点i到根节点路径上的异或值。对于两个不在同一条链上的节点s和e,如果它们的异或值相等,则可以推断出存在一个子路径的异或值为0,此时答案应增加size[s]*size[e]。如果两个节点位于同一链上(深度depth[e]>depth[s]),则令f为s的子节点且是e的祖先,答案应增加size[e]*(n-size[f])。由于异或值可能非常大,使用unordered_map来存储异或值及其出现次数,从而有效处理这种情况。

代码实现:

#include 
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int MAXN = 1e5 + 5;
unordered_map mp;
ll n, sz[MAXN], Xor[MAXN], ans;
vector> adj[MAXN];

void dfs_size(int s, int pre) {
sz[s] = 1;
for (auto &edge : adj[s]) {
int e = edge.first;
if (e != pre) {
Xor[e] = Xor[s] ^ edge.second;
dfs_size(e, s);
sz[s] = (sz[s] + sz[e]) % MOD;
}
}
}

void dfs_fork(int s, int pre) {
ans = (ans + sz[s] * mp[Xor[s]]) % MOD;
for (auto &edge : adj[s]) {
int e = edge.first;
if (e != pre)
dfs_fork(e, s);
}
mp[Xor[s]] = (mp[Xor[s]] + sz[s]) % MOD;
}

void dfs_line(int s, int pre) {
ans = (ans + mp[Xor[s]] * sz[s]) % MOD;
for (auto &edge : adj[s]) {
int e = edge.first;
if (e != pre) {
mp[Xor[s]] += (n - sz[e]);
dfs_line(e, s);
mp[Xor[s]] -= (n - sz[e]);
}
}
}

int main() {
cin >> n;
for (int i = 2; i <= n; ++i) {
int fa;
ll c;
cin >> fa >> c;
adj[fa].emplace_back(i, c);
adj[i].emplace_back(fa, c);
}
dfs_size(1, -1);
mp.clear();
dfs_fork(1, -1);
mp.clear();
dfs_line(1, -1);
cout < return 0;
}

推荐阅读
  • 本题要求计算给定两个正整数a和b时,2的-a次方与2的-b次方之和,并将结果以最简分数形式表示。输入包括多组测试数据,每组数据包含两个在2到20范围内的整数。 ... [详细]
  • 本文介绍了如何使用JFreeChart库创建一个美观且功能丰富的环形图。通过设置主题、字体和颜色等属性,可以生成符合特定需求的图表。 ... [详细]
  • 本题探讨在特定条件下如何通过选择瓶子以最大化从火星人处获取的燃料量。 ... [详细]
  • 深入解析Hadoop的核心组件与工作原理
    本文详细介绍了Hadoop的三大核心组件:分布式文件系统HDFS、资源管理器YARN和分布式计算框架MapReduce。通过分析这些组件的工作机制,帮助读者更好地理解Hadoop的架构及其在大数据处理中的应用。 ... [详细]
  • 深入浅出TensorFlow数据读写机制
    本文详细介绍TensorFlow中的数据读写操作,包括TFRecord文件的创建与读取,以及数据集(dataset)的相关概念和使用方法。 ... [详细]
  • 本文详细探讨了Java命令行参数的概念、使用方法及在实际编程中的应用,包括如何通过命令行传递参数给Java程序,以及如何在Java程序中解析这些参数。 ... [详细]
  • 通过分析和解决找零钱问题,深入理解贪心算法的应用。本文提供详细的C语言代码实现及解析。 ... [详细]
  • 本文探讨了一段包含基类与派生类的C++代码,重点分析了虚函数的调用机制及其对程序行为的影响。代码示例包括了两个类的定义:Base和Derived,以及它们之间的继承关系。 ... [详细]
  • 本文详细介绍了Linux内核中misc设备驱动框架的实现原理及应用方法,包括misc设备的基本概念、驱动框架的初始化过程、数据结构分析以及设备的注册与注销流程。 ... [详细]
  • 1、字符型常量字符型常量指单个字符,是用一对单引号及其所括起来的字符表示。例如:‘A’、‘a’、‘0’、’$‘等都是字符型常量。C语言的字符使用的就是 ... [详细]
  • 本文详细介绍了Java集合框架中的Collection体系,包括集合的基本概念及其与数组的区别。同时,深入探讨了Comparable和Comparator接口的区别,并分析了各种集合类的底层数据结构。最后,提供了如何根据需求选择合适的集合类的指导。 ... [详细]
  • [Vue.js 3.0] Guide – Scaling Up – State Management
    [Vue.js 3.0] Guide – Scaling Up – State Management ... [详细]
  • 烤鸭|本文_Spring之Bean的生命周期详解
    烤鸭|本文_Spring之Bean的生命周期详解 ... [详细]
  • 本文详细介绍了JSP(Java Server Pages)的九大内置对象及其功能,探讨了JSP与Servlet之间的关系及差异,并提供了实际编码示例。此外,还讨论了网页开发中常见的编码转换问题以及JSP的两种页面跳转方式。 ... [详细]
  • 华硕主板BIOS更新指南(图文)
    本文详细介绍了如何安全有效地更新华硕主板的BIOS,包括准备工作、具体步骤以及注意事项。BIOS是计算机基本输入输出系统的关键组成部分,负责初始化硬件并加载操作系统,定期更新BIOS可以增强系统的稳定性和兼容性。 ... [详细]
author-avatar
这个世界我看不懂2011_595
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有