题面传送门

一道推式子题。

首先列出柿子,\(ans=\sum\limits_{T_2}|T_1\cap T_2|·2^{T_1\cap T_2}\)

这个东西没法直接处理,不过注意到有一个柿子 \(f(S)=\sum\limits_{T\subseteq S}\sum\limits_{T'\subseteq T}(-1)^{T-T'}f(T')\),证明可考虑计算每个 \(T'\) 的贡献,由于 \(T'\subseteq T\subseteq S\),\(T\) 必然是 \(T'\) 与 \(S-T'\) 的某个子集的并,于是我们尝试枚举这个子集的大小,可得 \(T'\) 在对这个柿子结果的贡献为 \(f(T')\sum\limits_{i=0}^{|S-T'|}\dbinom{|S-T'|}{i}(-1)^i=0^{|S-T'|}·f(T')\),因此只有当 \(T'=S\) 时对结果产生 \(f(T')\) 的贡献,其余 \(T'\) 的贡献均为 \(0\),得证。

考虑将这个柿子应用于这道题上,记 \(f(S)=|S|·2^{|S|}\),那么

\[\begin{aligned}
ans&=\sum\limits_{T_2}f(T_1\cap T_2)\\
&=\sum\limits_{T_2}\sum\limits_{S\subseteq(T_1\cap T_2)}\sum\limits_{T\subseteq S}f(T)(-1)^{|S|-|T|}\\
&=\sum\limits_{S\in T_1}\sum\limits_{T\subseteq S}f(T)(-1)^{|S|-|T|}(\sum\limits_{S\in T_2}1)\\
&=\sum\limits_{S\in T_1}\sum\limits_{T\subseteq S}2^{|T|}·|T|·(-1)^{|S|\color{red}{+}|T|}(\sum\limits_{S\in T_2}1)\\
&=\sum\limits_{S\in T_1}(-1)^{|S|}\sum\limits_{T\subseteq S}(-2)^{|T|}·|T|·(\sum\limits_{S\in T_2}1)\\
&=\sum\limits_{S\in T_1}(-1)^{|S|}\sum\limits_{i=0}^{|S|}(-2)^i·i·\dbinom{|S|}{i}·(\sum\limits_{S\in T_2}1)\\
&=\sum\limits_{S\in T_1}(-1)^{|S|}\sum\limits_{i=0}^{|S|}(-2)^i·|S|·\dbinom{|S|-1}{i-1}·(\sum\limits_{S\in T_2}1)&\text{(吸收恒等式)}\\
&=\sum\limits_{S\in T_1}(-1)^{|S|}·|S|·\sum\limits_{i=0}^{|S|-1}(-2)^{i+1}·\dbinom{|S|-1}{i}·(\sum\limits_{S\in T_2}1)\\
&=\sum\limits_{S\in T_1}(-1)^{|S|}·|S|·(-2)·\sum\limits_{i=0}^{|S|-1}(-2)^{i}·\dbinom{|S|-1}{i}·1^{|S|-1-i}·(\sum\limits_{S\in T_2}1)\\
&=\sum\limits_{S\in T_1}(-1)^{|S|}·|S|·(-2)·(-1)^{|S|-1}·(\sum\limits_{S\in T_2}1)\\
&=\sum\limits_{S\in T_1}2|S|·(\sum\limits_{S\in T_2}1)
\end{aligned}
\]

推到这里,聪明的你一定已经发现,\(\sum\limits_{S\in T_2}1\) 就是包含 \(S\) 当中边的生成树个数,于是题目要求的就是对于所有边集 \(S\),包含 \(S\) 的生成树个数乘上 \(S\) 的大小之和,而又根据我们在这里推得的结论:包含 \(S\) 的生成树个数就是 \(n^{r-2}\prod\limits_{i=1}^ra_i\),其中 \(r\) 为 \(S\) 中的边形成的连通块个数,\(a_1,a_2,\cdots,a_r\) 为这 \(r\) 个连通块的大小。

于是答案可进一步可进一步写成 \(2\sum\limits_{S\in T_1}|S|n^{r-2}\prod\limits_{i=1}^ra_i=\dfrac{2}{n^2}\sum\limits_{S\in T_1}|S|\prod\limits_{i=1}^rna_i\),此时这玩意儿的组合意义就异常明显了:选择一个边集将这棵树分成若干个连通块,再从每个连通块中选择一个点,产生 \(n\) 的乘积贡献,最后从选定的边集中选择一条边,球所有选法的贡献之和。

这样就可以 DP 了,\(dp_{u,0/1,0/1}\) 表示确定了以 \(u\) 为根的子树内连通块的划分情况,\(u\) 所在的连通块是否选择了点,\(u\) 子树内是否有边被选择的方案数,树上背包转移即可。

时间复杂度 \(\mathcal O(16n)\)(虽然我深知这个写法非常不规范/cy/cy)

const int MAXN=2e6;
const int MOD=998244353;
int qpow(int x,int e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
int n,hd[MAXN+5],to[MAXN*2+5],nxt[MAXN*2+5],ec=0;
void adde(int u,int v){to[++ec]=v;nxt[ec]=hd[u];hd[u]=ec;}
int dp[MAXN+5][2][2],tmp[2][2];
void dfs(int x,int f){
dp[x][0][0]=1;dp[x][1][0]=n;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e];if(y==f) continue;dfs(y,x);fill0(tmp);
for(int p=0;p<2;p++) for(int q=0;q<2;q++)//not seperate and not choose
for(int u=0;u+p<2;u++) for(int v=0;v+q<2;v++)
tmp[u+p][v+q]=(tmp[u+p][v+q]+1ll*dp[x][p][q]*dp[y][u][v])%MOD;
for(int p=0;p<2;p++) for(int u=0;u+p<2;u++) tmp[u+p][1]=(tmp[u+p][1]+1ll*dp[x][p][0]*dp[y][u][0])%MOD;//not seperate and choose
for(int p=0;p<2;p++) for(int q=0;q<2;q++) for(int v=0;v+q<2;v++)//seperate
tmp[p][v+q]=(tmp[p][v+q]+1ll*dp[x][p][q]*dp[y][1][v])%MOD;
for(int p=0;p<2;p++) for(int q=0;q<2;q++) dp[x][p][q]=tmp[p][q];
} //printf("%d %d %d %d %d\n",x,dp[x][0][0],dp[x][0][1],dp[x][1][0],dp[x][1][1]);
}
int main(){
scanf("%d",&n);
for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),adde(u,v),adde(v,u);
dfs(1,0);printf("%d\n",2ll*qpow(n,MOD-3)*dp[1][1][1]%MOD);
return 0;
}

LOJ 3399 -「2020-2021 集训队作业」Communication Network(推式子+组合意义+树形 DP)的更多相关文章

  1. 「2020-2021 集训队作业」Yet Another Linear Algebra Problem(行列式,Binet-Cauchy 公式)

    题面 出题人:T L Y \tt TLY TLY 太阳神:Tiw_Air_OAO 「 2020 - 2021 集 训 队 作 业 」 Y e t A n o t h e r L i n e a r A ...

  2. Loj #2731 「JOISC 2016 Day 1」棋盘游戏

    Loj 2731 「JOISC 2016 Day 1」棋盘游戏 JOI 君有一个棋盘,棋盘上有 \(N\) 行 \(3\) 列 的格子.JOI 君有若干棋子,并想用它们来玩一个游戏.初始状态棋盘上至少 ...

  3. [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞

    [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞 试题描述 到河北省 见斯大林 / 在月光下 你的背影 / 让我们一起跳舞吧 うそだよ~ 河北省怎么可能有 Stalin. ...

  4. loj #6250. 「CodePlus 2017 11 月赛」找爸爸

    #6250. 「CodePlus 2017 11 月赛」找爸爸 题目描述 小 A 最近一直在找自己的爸爸,用什么办法呢,就是 DNA 比对. 小 A 有一套自己的 DNA 序列比较方法,其最终目标是最 ...

  5. LOJ 2737 「JOISC 2016 Day 3」电报 ——思路+基环树DP

    题目:https://loj.ac/problem/2737 相连的关系形成若干环 / 内向基环树 .如果不是只有一个环的话,就得断开一些边使得图变成若干链.边的边权是以它为出边的点的点权. 基环树的 ...

  6. LOJ 2736 「JOISC 2016 Day 3」回转寿司 ——堆+分块思路

    题目:https://loj.ac/problem/2736 如果每个询问都是 l = 1 , r = n ,那么每次输出序列的 n 个数与本次操作的数的最大值即可.可以用堆维护. 不同区间的询问,可 ...

  7. LOJ 510: 「LibreOJ NOI Round #1」北校门外的回忆

    题目传送门:LOJ #510. 题意简述: 给出一个在 \(K\) 进制下的树状数组,但是它的实现有问题. 形式化地说,令 \(\mathrm{lowbit}(x)\) 为在 \(K\) 进制下的 \ ...

  8. loj 2392「JOISC 2017 Day 1」烟花棒

    loj 答案显然满足二分性,先二分一个速度\(v\) 然后显然所有没有点火的都会往中间点火的人方向走,并且如果两个人相遇不会马上点火,要等到火快熄灭的时候才点火,所以这两个人之后应该在一起行动.另外有 ...

  9. @loj - 6353@「CodePlus 2018 4 月赛」组合数问题 2

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 请你找到 k 个不同的组合数,使得对于其中任何一个组合数 \(C ...

随机推荐

  1. Linux命令查看内存、整体负载、端口查看、进程查看、vim编辑器(3)

    一.资源占用命令   1.查看内存(free) free命令默认是以kb为单位显示的. free -m用Mb单位来显示. free -h显示单位 . free -h -s 3 ,每隔三秒刷新一次,如果 ...

  2. python使用Django框架开发简单项目

    一. (1)使用idea生成一个python项目,安装Django框架: pip install django==1.8.2 (2)初始化项目: django-admin startproject x ...

  3. 21.6.25 test

    \(NOI\) 模拟赛 \(T1\) 是树+位运算+dp+优化 打了 \(O(n^2)\) 的暴力dp,只拿到了35分,算了一下参赛的,人均65,中位数60.也能看出一些问题,对于一些模糊的猜测应该尝 ...

  4. 关于axios 的responseType类型的设置

    responseType值的类型可为如下 axios请求下载导出一个文件,请求成功时返回的是一个流形式的文件,需要设置responseType: 'arraybuffer',但是请求失败的需要返回的是 ...

  5. (一)Mongodb学习之 Centos 7 单机部署

    学习参考:https://www.runoob.com/mongodb/mongodb-tutorial.html 一.部署环境 1.系统:Centos 7 2.mongodb: mongodb-li ...

  6. httprunner3源码解读(3)client.py

    源码目录结构 ApiResponse 这个类没啥好说的 class ApiResponse(Response): """ 继承了requests模块中的Response类 ...

  7. DOS常用基本命令

    通配符* 和 ? *表示一个字符串 ?只代表一个字符 注意通配符只能通配文件名或扩展名,不能全都表示.例如我们要查找以字母y开头的所有文件,可以输入以下命令: dir y*.* 例如我要查找第二个字母 ...

  8. redis学习笔记(详细)——高级篇

    redis学习笔记(详细)--初级篇 redis学习笔记(详细)--高级篇 redis配置文件介绍 linux环境下配置大于编程 redis 的配置文件位于 Redis 安装目录下,文件名为 redi ...

  9. Charles抓包 mock数据和rewrite功能

    一.mock数据 mock:在后端返回异常或需要=改前端展示的数据时可以模拟返回的response 1.1 抓到接口后 右击保存response到本地,后缀改成.json打开可以看到是把json保存下 ...

  10. Go语言核心36讲(Go语言实战与应用二)--学习笔记

    24 | 测试的基本规则和流程(下) Go 语言是一门很重视程序测试的编程语言,所以在上一篇中,我与你再三强调了程序测试的重要性,同时,也介绍了关于go test命令的基本规则和主要流程的内容.今天我 ...