解题报告-小 A 的树

news/2025/10/3 10:04:30/文章来源:https://www.cnblogs.com/Starpop/p/19124354

小 A 的树

题目描述

小 A 有一棵 \(N\) 个点的树,每个点都有一个小于 \(2^{20}\) 的非负整数权值。现在小 A 从树中随机选择一个点 \(x\),再随机选择一个点 \(y\)\(x\)\(y\)可以是同一个点),并对从 \(x\)\(y\) 的路径上 所有的点的权值分别做按位与、按位或、异或运算,最终会求得三个整数。小 A 想知道,他求出的三个数的期望值分别是多少。

输入描述

输入包含多组测试数据。

第一行,一个整数 \(T\),表示测试数据的组数。

接下来 \(T\) 节,每节表示一组测试数据,格式如下:

  • 第一行,一个整数 \(N\)
  • 第二行,\(N\) 个整数,其中第 \(i\) 个整数表示第 \(i\) 个点的权值。
  • 接下来 \(N-1\) 行,每行两个整数 \(u\)\(v\),表示树中有一条连接 \(u\)\(v\) 的边。

输出描述

\(T\) 行,每行三个浮点数,保留三位小数,其中第 \(i\) 行的三个浮点数表示第 \(i\) 组数据对应的按位与、按位或、异或的期望。

输入输出描述 #1

输入样例 #1

1
4
1 2 3 4
1 2
2 3
2 4

输出样例 #1

0.875 4.250 3.375

提示/说明

数据范围

  • 对于 \(20\)% 的数据,\(1 \leq N \leq 10^3\)
  • 另外 \(20\)% 的数据,\(N\) 个点构成一条链。
  • 对于 \(100\)% 的数据,\(1 \leq N \leq 10^5\)\(1\leq T\leq 5\)

对于不同路径的判断

设有两个树上的点 \(u\)\(v\)

  • \(u=v\),则路径 \(u \rightarrow v\) 和路径 \(v \rightarrow u\) 是相同路径。
  • \(u \neq v\),则路径 \(u \rightarrow v\) 和路径 \(v \rightarrow u\) 是不同路径。

解题报告

神秘树形 DP。

首先要有一个思路:按位与、按位或、异或三个运算都是各进制位独立运算,可以考虑分开进行

所以,我们可以求出三个运算使每个二进制位为 \(1\) 的期望,最后统计总期望。

由于总路径数量一定,为 \(N \times N\),所以我们对于每个运算只需求出可以使每个二进制位为 \(1\) 的路径数。

一个很常见的思路:对于每个在以 \(u\) 为根的子树,统计以 \(u\) 为一个端点的路径的价值,再转换成每条在以 \(u\) 为根的子树的路径的价值。其实就是把 \(u\) 作为 LCA 的路径 \(s \rightarrow t\),把这条路径分成 \(s \rightarrow u\)\(u \rightarrow t\) 两天路径,单独处理出每个 \(s \rightarrow u\)\(u \rightarrow t\) 的路径的价值,既可以计算出每个路径的价值。

然后就是一个简单的树形 DP。

\(dp[u][i][0/1/2]\) 分别表示以节点 \(u\) 的子树中以 \(u\) 为端点的路径中按位与、按位或、异或后可以使第 \(i\) 个二进制位为 \(1\) 的路径数。

\(val[u][i]\) 表示节点 \(u\) 的权值第 \(i\) 个二进制位状态。

\(siz[u]\) 表示子树 \(u\) 的大小,同时也等价于子树内以 \(u\) 为端点的路径的条数。

\(v\)\(u\) 的一个子节点。

转移方程很好推,代码如下:

for(int i=1;i<M;j++)
{if(val[u][i]){dp[u][i][0]+=dp[v][i][0];dp[u][i][1]+=siz[v];dp[u][i][2]+=siz[v]-dp[v][i][2];}else{dp[u][i][1]+=dp[v][j][1];dp[u][j][2]+=dp[v][i][2];}
}

然后就可以对子树 \(u\) 分别统计三个运算中使第 \(i\) 个二进制位为 \(1\) 的路径总数 \(cnt[0/1/2][i]\)

// 统计u->u的路径
for(int j=1;j<M;j++)
{cnt[0][j]+=val[u][j];cnt[1][j]+=val[u][j];cnt[2][j]+=val[u][j];
}// 统计子树内经过 u 且起始点不同的路径
for(auto v:e[u])
{if(v==fa) continue;for(int j=1;j<M;j++){cnt[0][j]+=2*dp[u][i][0]*dp[v][i][0];cnt[1][j]+=2*(siz[u]*siz[v]-(siz[u]-dp[u][j][1])*(siz[v]-dp[v][j][1]));cnt[2][j]+=2*(dp[u][j][2]*(siz[v]-dp[v][j][2])+dp[v][j][2]*(siz[u]-dp[u][j][2]));}
}

然后统计答案就好了,总代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1001100;
const int M=32;#define ckmax(x,y) ( x=max(x,y) )
#define ckmin(x,y) ( x=min(x,y) )inline int read()
{int f=1,x=0; char ch=getchar();while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); }while(isdigit(ch))  { x=x*10+ch-'0';    ch=getchar(); }return f*x;
}struct node
{int siz;int f[3][M];bool val[M];
}p[N];
int n;
int cnt[3][M];
vector<int> e[N];inline void addedge(int u,int v)
{e[u].push_back(v);e[v].push_back(u);
}inline void Clear()
{memset(cnt,0,sizeof(cnt));for(int i=1;i<=n;i++){memset(p[i].val,0,sizeof(p[i].val));memset(p[i].f,0,sizeof(p[i].f));p[i].siz=0;e[i].clear();}
}inline void debug(int u)
{printf("%d\n",u);for(int i=1;i<M;i++)printf("%d ",p[u].val[i]);cout<<endl;for(int j= 0;j<3;j++,putchar('\n'))for(int i=1;i<M;i++,putchar(' '))cout<<p[u].f[j][i];cout<<endl<<endl;
}void dfs(int u,int fa)
{p[u].siz=1;for(int i=0;i<e[u].size();i++){int v=e[u][i];if(v==fa) continue;dfs(v,u);for(int j=1;j<M;j++){cnt[0][j]+=2*p[u].f[0][j]*p[v].f[0][j];cnt[1][j]+=2*(p[u].siz*p[v].siz-(p[u].siz-p[u].f[1][j])*(p[v].siz-p[v].f[1][j]));cnt[2][j]+=2*(p[u].f[2][j]*(p[v].siz-p[v].f[2][j])+p[v].f[2][j]*(p[u].siz-p[u].f[2][j]));}p[u].siz+=p[v].siz;for(int j=1;j<M;j++){if(p[u].val[j]){p[u].f[0][j]+=p[v].f[0][j];p[u].f[1][j]+=p[v].siz;p[u].f[2][j]+=p[v].siz-p[v].f[2][j];}else{p[u].f[1][j]+=p[v].f[1][j];p[u].f[2][j]+=p[v].f[2][j];}}}// debug(u);
}signed main()
{freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);int Q=read();while(Q--){n=read();for(int i=1;i<=n;i++){int x=read();for(int j=1;j<M;j++){p[i].val[j]=(x>>j-1)&1;p[i].f[0][j]=p[i].val[j];p[i].f[1][j]=p[i].val[j];p[i].f[2][j]=p[i].val[j];cnt[0][j]+=p[i].val[j];cnt[1][j]+=p[i].val[j];cnt[2][j]+=p[i].val[j];}}for(int i=1;i<n;i++)addedge(read(),read());dfs(1,0);int tot=n*n;double ans0=0,ans1=0,ans2=0;for(int i=1;i<M;i++){int tmp=(1<<i-1);ans0+=(double)tmp*cnt[0][i]/(double)tot;ans1+=(double)tmp*cnt[1][i]/(double)tot;ans2+=(double)tmp*cnt[2][i]/(double)tot;}printf("%.3lf %.3lf %.3lf\n",ans0,ans1,ans2);Clear();}return 0;
}

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

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

相关文章

【React 状态管理深度解析:Object.is()、Hook 机制与 Vue 对比实践指南】 - 教程

【React 状态管理深度解析:Object.is()、Hook 机制与 Vue 对比实践指南】 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font…

2025 --【J+S 二十连测】-- 第一套 总结

总结 T1 考场上很快写出了正解,没有问题 T2 考场上很快写出了正解,但提交时交了两边,故0分 T3 考场上很快写出了正解,没有问题 T4 考场上很快写出了部分分,拿满了,没有问题 题解 T1 照题意模拟即可 代码 #includ…

详细介绍:分布式缓存的正确姿势:Cache-Aside、更新策略与分布式锁在 Java 微服务中的实战

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

企业网站建设的文章太原市做网站

AI的归纳和演绎法分别是什么&#xff1f; AI的归纳和演绎法是两种常见的推理方法。 归纳法&#xff08;inductive reasoning&#xff09;是一种从特殊到一般的过程&#xff0c;在有限的实例观察中得出一般规律或原则。用简单的说法&#xff0c;就是从一些具体的事物或情况中总…

做网站大彩票网站开发搭建

《绝地求生》PCL秋季赛的战斗已经全部落下帷幕了&#xff0c;Team Razer 雷蛇战队成员&#xff0c;国内最具人气的4AM战队凭借着在季后赛的出色发挥&#xff0c;以316分的高分碾压全场&#xff0c;成功斩获本次PCL秋季赛的冠军&#xff0c;成为PCL联赛首个双冠队伍。随着金色的…

个人网站建设服务器aaa云主机怎么做网站

1、基本操作 1.1、进入HBase客户端命令行 前提是先启动hadoop集群和zookeeper集群。 bin/hbase shell 1.2、查看帮助命令 helphelp 查看指定命令的语法规则 查看 list_namespace 的用法&#xff08;‘记得加单引号’&#xff09; help list_namespace 2、namespace 我们…

信阳市网站建设自己做服装搭配的网站

Docker Compose是一种流行的技术&#xff0c;可以用来定义和管理你的应用程序所需的多个服务容器。通常在你的应用程序旁边创建一个 compose.yml 文件&#xff0c;它定义和配置服务容器。 使用 Docker Compose 的典型工作流程是运行 docker compose up&#xff0c;用它连接启动…

网站建设优化服务方案模板西安商城网站建设

前言 spring作为主流的 Java Web 开发的开源框架&#xff0c;是Java 世界最为成功的框架&#xff0c;持续不断深入认识spring框架是Java程序员不变的追求。 本篇博客介绍SpringBootApplicant注解的自动加载相关内容 其他相关的Spring博客文章列表如下&#xff1a; Spring基…

【实验报告】华东理工大学随机信号处理实验报告 - 详解

【实验报告】华东理工大学随机信号处理实验报告 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&q…

网站建设都包含哪些内容wordpress 更新网站

print() 在控制台输出 input() 获取控制台输⼊的内容 type() 获取变量的数据类型 len() 获取容器的⻓度 (元素的个数) range() ⽣成⼀个序列[0, n) 以上都是我们学过的函数&#xff0c;函数可以实现⼀个特定的功能。我们将学习⾃⼰如何定义函数, 实现特定的功能。 1.函数是什么…

页面置换算法

最佳置换算法opt 类似于cache 每次选择淘汰的页面将是以后永不使用的,或者在最长时间不会被访问的页面,这样可以保证最低的缺页率 缺页时未必发生页面置换,若还有可用的空闲内存块,就不用进行页面置换 缺页率=缺页…

Docker部署配置全流程(超详细——Windows和Linux) - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

推进电子设计革新:仿真(Emulation)如何引领下一代验证方式

在 IC 设计领域,硬件仿真(也称 FPGA 原型验证)已经跃升为不可或缺的关键技术。它以近乎真实硬件的形式重构目标设计,帮助工程师在硅片制造前进行高精度验证,为安全性、性能与功能保驾护航。1、为什么硬件仿真如此…

佛山网站建设兼职小型企业网站如何建设

为什么游戏公司选择物理服务器 1、选择的自由 选择游戏物理服务器可让我们根据需要自由选择和配置硬件。在完成设置和配置新获得的游戏服务器的所有艰苦工作后&#xff0c;请始终查看我们获得的价格&#xff0c;以确保自己拥有足够的带宽资源、端口容量和CPU核心&#xff0c;以…

AT_abc309_g [ABC309G] Ban Permutation

做这种排列计数题不是很明白. 首先考虑 \(x\) 很小,但它范围是扣掉一段区间,很不好. 我们容斥 \(j\) 个位置不满足条件去 DP,每次状压 \([i - x + 1, i + x - 1]\) 里数的用的情况即可,需要注意开头结尾的时候填不满.

在Mac上运行Windows 365的完整指南

本文详细介绍如何在Mac设备上部署和运行Windows 365云电脑,比较网页客户端与原生应用的功能差异,并逐步说明配置步骤和可用功能,包括多显示器支持和外围设备重定向等关键技术特性。如何在Mac上运行Windows 365 IT团…

完整教程:华为海思正式进入Wi-Fi FEM赛道?

完整教程:华为海思正式进入Wi-Fi FEM赛道?2025-10-03 09:26 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: bl…

现在做微信开发网站多少钱创新产品设计

只听名字的话会感觉对偶单纯形法和对偶问题关系很大&#xff0c;其实不然(想要了解对偶问题的话可以看我之前的文章)。对偶单纯形法在我看来和大M法以及两阶段法很像&#xff0c;都是用来补充纯粹的单纯形法无法解决特殊问题的缺陷。而且对偶单纯形法更加“强大”&#xff0c;因…

摩刻S10 动感单车 速度传感器故障及更换!

前段时间骑行过程中发现仪表盘上速度偶尔为0,时间停止不走的情况。之后就完全为0,时间也不增长了。 之后询问官方客服人员说是速度传感器故障,需要更换,但需到官方制定店铺购买备件。 测试方式是在拆下的传感器接…

Flink 架构组件、任务链路、Slot 资源与集群形态 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …