[题解][P5206][WC2019] 数树 (op = 1)
简要题意
给定 \(n, y\)。
一张图有 \(|V| = n\) 个点,现在给出两棵树 \(T_1=G(V, E_1)\) 和 \(T_2=G(V, E_2)\)。
定义这两棵树的权值 \(F(E_1, E_2)\) 为 \(y\) 的 \(G'=(V,E_1\cap E_2)\) 的联通块个数次方。
即 \(F(E_1, E_2) = y^{n - |E_1\cap E_2|}\),给定 \(E_1\),计算 \(\sum_{E_2} F(E_1, E_2)\)。
其中 \(n\le 10^5\)。答案对 \(998244353\) 取模。
解题思路
首先我们要找到一个合适的形式来表示我们的答案,部分枚举 \(S=E_1\cap E_2\),则答案为:
\]
其中 \(S=E_1\cap E_2\) 这个恰好的条件限制较强,考虑容斥将限制弱化为 \(S\subseteq E_1\cap E_2\).
不妨考虑这样一个容斥原理的式子:
\]
代入到原来的式子中,得到:
&\sum_{E_2} \sum_{S=E_1\cap E_2} y^{n-|S|}\\
=&\sum_{E_2} \sum_{T\subseteq E_1\cap E_2} \sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\
=&\sum_{T\subseteq E_1}g(T)\sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\=&\sum_{T\subseteq E_1}g(T)y^{n-|T|}\sum_{P\subseteq T}(-y)^{|T|-|P|}\\
=&\sum_{T\subseteq E_1}g(T)\sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\=&\sum_{T\subseteq E_1}g(T)y^{n-|T|}\sum_{|P|=0}^{|T|}\binom{|T|}{|P|}(-y)^{|T|-|P|}\\
=&\sum_{T\subseteq E_1}g(T)\sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\=&\sum_{T\subseteq E_1}g(T)y^{n-|T|}(1-y)^{|T|}\\
\end{aligned}
\]
其中 \(g(T)\) 表示包含边集 \(T\) 的 \(E_2\) 的个数。
假设 \(G=(V,T)\) 为一个由 \(k\) 个大小分别为 \(a_i\) 的连通块组成的森林,则:
\]
继续代入 (注意到 \(n=|T|+k\) ),得:
&\sum_{T\subseteq E_1}g(T)y^{n-|T|}(1-y)^{|T|}\\
=&\sum_{T\subseteq E_1}n^{k-2}\prod_{i=1}^ka_i\ y^k(1-y)^{n-k}\\
=&\frac{(1-y)^n}{n^2}\sum_{T\subseteq E_1}\prod_{i=1}^k\frac{ny}{1-y}\ a_i
\end{aligned}
\]
即一个大小为 \(a\) 的连通块为答案贡献一个乘积 Ka,其中 \(K = \frac{ny}{1-y}\)。
据此可以容易得到一个 \(O(n^2)\) 的 DP,\(f(x,i)\) 表示 \(x\) 的子树中,\(x\) 所在的连通块大小为 \(i\) 的答案。
考虑到这个贡献可以拆分表示为 \(\prod_{i=1}^k(K+K+K+\cdots K)\),故合并两个大小分别为 \(x,y\) 的连通块时,新的贡献其实就是 \(K(x+y)\prod_{i\ne now}Ka_i\).
这样状态可以优化为 \(f(x,0/1)\) 表示 \(x\) 的子树中,当前连通块是否已经做出贡献。
那么转移就是 (前面是选边 \((x,y)\),后面是不选):
&f(x,1)=f(x,1)f(y,1)\ +\ f(x,1)f(y,0)+f(x,0)f(y,1)\\
&f(x,0)=f(x,0)f(y,1)\ +\ f(x,0)f(y,0)
\end{aligned}
\]
代码
void dfs(int x, int fx){
siz[x] = 1, f[x] = coef, g[x] = 1;
for(int i = head[x]; i; i = e[i].nx){
int y = e[i].to; if(y == fx) continue;
dfs(y, x);
int sum = Mod((LL) f[x] * g[y] % mod + (LL) g[x] * f[y] % mod - mod);
MOD(f[x] = (LL) f[x] * f[y] % mod + sum - mod);
MOD(g[x] = (LL) g[x] * f[y] % mod + (LL) g[x] * g[y] % mod - mod);
}
}
void solve(){
coef = (LL) n * y % mod * qpow(1 - y + mod) % mod;
dfs(1, 0);
cout << (LL) f[1] * qpow(1 - y + mod, n) % mod * qpow((LL) n * n % mod) % mod << endl;
}
[题解][P5206][WC2019] 数树 (op = 1)的更多相关文章
- 洛谷P5206 [WC2019] 数树(生成函数+容斥+矩阵树)
题面 传送门 前置芝士 矩阵树,基本容斥原理,生成函数,多项式\(\exp\) 题解 我也想哭了--orz rqy,orz shadowice 我们设\(T1,T2\)为两棵树,并定义一个权值函数\( ...
- 并不对劲的bzoj5475:loj2983:p5206:[wc2019]数树
题目大意 task0:有两棵\(n\)(n\leq10^5)个点的树\(T1,T2\),每个点的点权可以是一个在\([1,y]\)里的数,如果两个点既在\(T1\)中有直接连边,又在\(T2\)中有直 ...
- 洛谷 P5206 - [WC2019]数树(集合反演+NTT)
洛谷题面传送门 神仙多项式+组合数学题,不过还是被我自己想出来了( 首先对于两棵树 \(E_1,E_2\) 而言,为它们填上 \(1\sim y\) 使其合法的方案数显然是 \(y\) 的 \(E_1 ...
- 洛谷P5206 [WC2019]数树 [容斥,DP,生成函数,NTT]
传送门 Orz神仙题,让我长了许多见识. 长式子警告 思路 y=1 由于y=1时会导致后面一些式子未定义,先抓出来. printf("%lld",opt==0?1:(opt==1? ...
- 洛谷 P5206: bzoj 5475: LOJ 2983: [WC2019] 数树
一道技巧性非常强的计数题,历年WC出得最好(同时可能是比较简单)的题目之一. 题目传送门:洛谷P5206. 题意简述: 给定 \(n, y\). 一张图有 \(|V| = n\) 个点.对于两棵树 \ ...
- [WC2019] 数树
[WC2019] 数树 Zhang_RQ题解(本篇仅概述) 前言 有进步,只做了半天.... 一道具有极强综合性的数数好题! 强大的多合一题目 精确地数学推导和耐心. 有套路又不失心意. 融合了: 算 ...
- [LOJ2983] [WC2019] 数树
题目链接 LOJ:https://loj.ac/problem/2983 BZOJ:https://lydsy.com/JudgeOnline/problem.php?id=5475 洛谷:https ...
- BZOJ5475 WC2019数树(prufer+容斥原理+树形dp+多项式exp)
因为一大堆式子实在懒得写题解了.首先用prufer推出CF917D用到的结论,然后具体见前言不搭后语的注释. #include<iostream> #include<cstdio&g ...
- 【LuoguP5206】[WC2019] 数树
题目链接 题意 定义 \(F(T_1,T_2)=y^{n-common}\) 其中 \(common\) 为两棵树 \(T_1,T_2\) 的公共边条数. 三种问题 1.给定 \(T_1,T_2\) ...
随机推荐
- Java 中是如何支持正则表达式操作的?
Java 中的 String 类提供了支持正则表达式操作的方法,包括:matches(). replaceAll().replaceFirst().split().此外,Java 中可以用 Patte ...
- 什么叫线程安全?servlet 是线程安全吗?
线程安全是编程中的术语,指某个函数.函数库在多线程环境中被调用时,能够 正确地处理多个线程之间的共享变量,使程序功能正确完成. Servlet 不是线程安全的,servlet 是单实例多线程的,当多个 ...
- (转载)JSON对象使用变量作为键名
转载链接:https://blog.csdn.net/lihefei_coder/article/details/82499520 //第一种方式 var key = 'name'; var json ...
- Oracle 数据库备份实战
最近公司的客户希望使用oracle数据库,所以我们只好将数据从mysql数据库迁移到oracle数据库,并对oracle数据库制定了一个备份策略,之前虽然对oracle很熟悉,但做备份策略还是第一次, ...
- DRF 简单使用(详细注释版)
1.djangorestframework使用 下载安装 pip install djangorestframework ## djangorestframework pip install djan ...
- Effective Java —— 谨慎覆盖clone
本文参考 本篇文章参考自<Effective Java>第三版第十三条"Always override toString",在<阿里巴巴Java开发手册>中 ...
- Python - random库介绍
- Java/C++实现命令模式---多次撤销和撤回
某系统需要提供一个命令集合(注:可以使用链表,栈等集合对象实现),用于存储一系列命令对象,并通过该命令集合实现多次undo()和redo()操作,可以使用加法运算来模拟实现.\ 类图: Java代码: ...
- python入门-开始
1.为啥要学Python? 各种语言的优劣势对比视频版:https://www.bilibili.com/video/BV1y3411r7pX/?spm_id_from=autoNext 各种语言的优 ...
- MyBatis起步搭建
1 步骤 数据库环境 创建Maven项目 导入依赖 编写MyBatis配置文件 编写MyBatis工具类 编写实体类 编写Mapper 测试 2 数据库环境 MySQL 8.0版本 create da ...