CodeForces 1067E Random Forest Rank
题意
给定一棵 \(n\) 个节点的树,每条边有 \(\frac{1}{2}\) 的概率出现,这样会得出一个森林,求这个森林的邻接矩阵 \(A\) 的秩 \(\operatorname{rank} A\) 的期望。
\(\texttt{Data Range:}1\leq n\leq 5\times 10^5\)
题解
好题,正解是线性代数 + 期望 DP。其实是不知道结论感觉挺难只要知道结论就是 sb 题的题
首先来证明一个结论:一个森林邻接矩阵的秩为该森林最大匹配数目的两倍。
考虑 \(\operatorname{rank} A\) 的一个定义,也即非零子式的最高阶数。所以,设 \(\operatorname{rank}A=k\),我们只需要考虑一个 \(k\) 阶子式即可。很明显由于原图的邻接矩阵是对称矩阵,所以我们自然想去考虑一个对称的 \(k\) 阶子式,因为这个东西对应原图的一个导出子图。
同时,森林的导出子图还是森林,所以类似于二分,将最优化转化为判定,只要考虑一个森林的邻接矩阵什么情况下是满秩的即可。
注意到,对于 \(n\times n\) 的方阵 \(A\) 来说,\(\operatorname{rank} A=n\) 与 \(\det A\neq 0\) 等价。因为如果 \(\det A\neq 0\) 的话这个矩阵一定不是“压缩扁平化”的变换,也即 \(\dim \operatorname{Ker} A=0\),根据秩零化度定理即可得出。于是我们转为考察邻接矩阵的行列式,这里直接考虑定义:
\]
注意到,\(A_{i,\pi_i}\) 非零,表示图上存在一条 \((i,\pi_i)\) 的边。所以 \(\det A\) 非零当且仅当存在一个排列 \(\pi\) 使得 \((i,\pi_i)\) 存在边。
将这个排列写成置换的形式,可以分解成若干个循环。注意到考察的对象是森林,所以所有循环的长度只可能是 \(2\),也即一条边产生一个循环。
这个时候,可以将每个循环内的点两两匹配,很明显的,由于每个点都被匹配上了,这个匹配是完美匹配。
于是我们推出一个结论:对于一个森林的邻接矩阵 \(A\) 来说,\(\operatorname{rank} A=n\) 与森林有完美匹配是等价的。所以 \(\operatorname{rank} A\) 也就是原图的最大满足有完美匹配的导出子图的大小。考虑求出原图的一个最大匹配,因为没有比最大匹配更大的匹配,所以我们可以选原图的最大匹配作为导出子图。
通过上述的说明,我们成功证明了 \(\operatorname{rank} A\) 为最大匹配数目的两倍。
这个时候就变成求最大匹配数目的期望了。根据期望的线性性,设 \(f_u\) 表示 \(u\) 与一个孩子匹配的概率,那么答案为所有 \(f_u\) 的和。同时这个 \(f_u\) 的转移非常简单,就不做过多说明了。
代码
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=5e5+51,MOD=998244353,INV2=499122177;
struct Edge{
ll to,prev;
};
Edge ed[MAXN<<1];
ll n,tot,from,to,res,c;
ll last[MAXN],f[MAXN];
namespace FastIO{
char buf[MAXN*5],*st=buf,*ed=buf;
inline char gc()
{
return st==ed&&(ed=(st=buf)+fread(buf,1,2500000,stdin),ed==st)?0:*st++;
}
}
using FastIO::gc;
inline ll read()
{
register ll num=0;
register char ch=gc();
while(!isdigit(ch)&&ch!='-')
{
ch=gc();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=gc();
}
return num;
}
inline void addEdge(ll from,ll to)
{
ed[++tot].prev=last[from];
ed[tot].to=to;
last[from]=tot;
}
inline void dfs(ll node,ll fa)
{
ll prod=1;
for(register int i=last[node];i;i=ed[i].prev)
{
if(ed[i].to!=fa)
{
dfs(ed[i].to,node),prod=(li)prod*(1+f[ed[i].to])%MOD*INV2%MOD;
}
}
res=(res+(f[node]=MOD+1-prod))%MOD;
}
int main()
{
n=read(),c=1;
for(register int i=0;i<n-1;i++)
{
from=read(),to=read(),addEdge(from,to),addEdge(to,from),c=(c+c)%MOD;
}
dfs(1,0),printf("%d\n",(li)res*(c+c)%MOD);
}
CodeForces 1067E Random Forest Rank的更多相关文章
- Codeforces 1067E - Random Forest Rank(找性质+树形 dp)
Codeforces 题面传送门 & 洛谷题面传送门 一道不知道能不能算上自己 AC 的 D1E(?) 挺有意思的结论题,结论倒是自己猜出来了,可根本不会证( 开始搬运题解 ing: 碰到这样 ...
- CF1067E Random Forest Rank
CF1067E Random Forest Rank 可以证明: 一个树的邻接矩阵的秩,等于最大匹配数*2(虽然我只能证明下界是最大匹配) 而树的最大匹配可以贪心, 不妨用DP模拟这个过程 f[x][ ...
- [Machine Learning & Algorithm] 随机森林(Random Forest)
1 什么是随机森林? 作为新兴起的.高度灵活的一种机器学习算法,随机森林(Random Forest,简称RF)拥有广泛的应用前景,从市场营销到医疗保健保险,既可以用来做市场营销模拟的建模,统计客户来 ...
- paper 85:机器统计学习方法——CART, Bagging, Random Forest, Boosting
本文从统计学角度讲解了CART(Classification And Regression Tree), Bagging(bootstrap aggregation), Random Forest B ...
- paper 56 :机器学习中的算法:决策树模型组合之随机森林(Random Forest)
周五的组会如约而至,讨论了一个比较感兴趣的话题,就是使用SVM和随机森林来训练图像,这样的目的就是 在图像特征之间建立内在的联系,这个model的训练,着实需要好好的研究一下,下面是我们需要准备的入门 ...
- 多分类问题中,实现不同分类区域颜色填充的MATLAB代码(demo:Random Forest)
之前建立了一个SVM-based Ordinal regression模型,一种特殊的多分类模型,就想通过可视化的方式展示模型分类的效果,对各个分类区域用不同颜色表示.可是,也看了很多代码,但基本都是 ...
- Ensemble Learning 之 Bagging 与 Random Forest
Bagging 全称是 Boostrap Aggregation,是除 Boosting 之外另一种集成学习的方式,之前在已经介绍过关与 Ensemble Learning 的内容与评价标准,其中“多 ...
- Aggregation(1):Blending、Bagging、Random Forest
假设我们有很多机器学习算法(可以是前面学过的任何一个),我们能不能同时使用它们来提高算法的性能?也即:三个臭皮匠赛过诸葛亮. 有这么几种aggregation的方式: 一些性能不太好的机器学习算法(弱 ...
- codeforces 478B Random Teams
codeforces 478B Random Teams 解题报告 题目链接:cm.hust.edu.cn/vjudge/contest/view.action?cid=88890#probl ...
随机推荐
- AI小白必读:深度学习、迁移学习、强化学习别再傻傻分不清
摘要:诸多关于人工智能的流行词汇萦绕在我们耳边,比如深度学习 (Deep Learning).强化学习 (Reinforcement Learning).迁移学习 (Transfer Learning ...
- pormise和async
pormise 1.异步问题 假设现在我刚认识你,需要和你说话,但是我普通话不够标准,需要间隔一秒钟才能说一句话,以此让你可以慢慢思考.这样的话我们就需要用到定时器. 最沙雕的代码如下: setTim ...
- Python-输入输出-input ouput
输入.输出? 这种统称为IO流,也就是数据流向,在标准中,从终端输入称为标准输入 sidin,从终端输出为标准输出 stdout,从终端错误输出则为标准错误输出 stderr.这些只是IO流中终端方面 ...
- spring-boot-route(五)整合Swagger生成接口文档
目前,大多数公司都采用了前后端分离的开发模式,为了解决前后端人员的沟通问题,后端人员在开发接口的时候会选择使用swagger2来生成对应的接口文档,swagger2提供了强大的页面调试功能,这样可以有 ...
- 程序员你是如何使用Nacos作为配置中心的?
假如你使用的是spring-cloud-alibaba微服务技术栈 单个服务独有配置文件 即去除应用程序的状态,配置统一外部化管理,方便进行水平的伸缩. 集成步骤: 假如我有一个应用app-desig ...
- 第0天 | 12天搞定Pyhon,前言
依稀记得,在2014年的某一天,一位运营电商平台的多年好朋友,找我帮忙:一个月内,实现抓取竞争对手在某电商平台上的所有产品信息并统计每个产品的点击率. 说出来有些不好意思,那些年,参与过的产品挺多的, ...
- 解读JVM虚拟机
概要点: java虚拟机概述和基本概念 堆.栈.方法区 了解虚拟机参数 垃圾回收概念和算法.及对象的分代转换 垃圾收集器 java虚拟机的原理: 所谓虚拟机,就是一台虚拟的机器.它是一款软件,用来执行 ...
- MeteoInfoLab脚本示例:MODIS Sinusoidal投影HDF数据
MODIS卫星很多陆面数据都是Sinusoidal投影,数据被分为一个个10*10度(赤道地区)的瓦片(http://modis-land.gsfc.nasa.gov/MODLAND_grid.htm ...
- 我不信这篇文章能让你学会C语言,但是我还是想分享一下!
前言 C 语言是一门抽象的.面向过程的语言,C 语言广泛应用于底层开发,C 语言在计算机体系中占据着不可替代的作用,可以说 C 语言是编程的基础,也就是说,不管你学习任何语言,都应该把 C 语言放在首 ...
- elk-日志方案--使用Filebeat收集日志并输出到Kafka
1,Filebeat简介 Filebeat是一个使用Go语言实现的轻量型日志采集器.在微服务体系中他与微服务部署在一起收集微服务产生的日志并推送到ELK. 在我们的架构设计中Kafka负责微服务和 ...