NFLSOJ #10317. -「2020联考北附2」三千世界(找等价表达+树形 dp)
出题人可能原本感觉没啥难度的 T2 竟然变成了防 AK 题,奇迹奇迹(
首先带着这个 \(\max\) 肯定不太好处理,考虑找出 \(f(S)\) 的等价表达。我们考虑以 \(1\) 为根 DFS 一遍整棵树,然后考虑贪心。每次贪心地找到所有路径中 LCA 最深的路径,如果这条路径上所有节点都没被访问过我们就将该路径上所有节点都设为被访问过并令答案加一,否则我们直接不管这条路径。感性理解一下可知我们采取这样的策略肯定能取到较多的路径。
接下来考虑求答案的事。考虑方案数转期望,我们求出每个点有多大概率作为某个被选择路径的 LCA 出现过,然后把它们加起来再乘上 \(2^{n^2}\) 就是答案。那么怎么求呢?注意到对于一个点如果它的某个祖先被访问了,那么这个点也没有用了。因此我们可以将选择一条路径视作直接将这个子树吃掉(虽然这样说好像有点奇怪?),这样就可以 DP 了,我们设 \(dp_{u,j}\) 表示钦定了 LCA 在 \(u\) 子树内的路径,还有 \(j\) 个点没有被吃掉的概率,转移就将两个子树合并起来即可,设 \(u\) 为 \(v\) 的父亲,那么显然 \(dp_{u,0}\) 只能转移到新的 \(dp_{u,0}\),而对于 \(i\ne 0\),\(j\in[0,siz_y]\),\(dp_{u,i}\) 和 \(dp_{v,j}\) 有 \(\dfrac{1}{2^{2ij}}\) 的概率转移到 \(dp_{u,i+j}\),有 \(1-\dfrac{1}{2^{2ij}}\) 的概率转移到 \(dp_{u,0}\)。树上背包求一下即可。最终 \(dp_{i,0}\) 即为 \(i\) 作为某条路径 LCA 出现的概率。时间复杂度 \(\mathcal O(n^2)\)。
总结:为什么这样的题目要找出 \(f(S)\) 的等价表达?因为这里的 \(f(S)\) 是一个找最大值的形式,而求一车东西的 \(\max\) 这个东西是很难计算的(当然有些情况下确实是可以,不过要用 Min-Max 容斥等技巧,并且局限性比较大),(当然有的数据范围很小的题目也可以用这个做法,比方说一些 DP 套 DP,如 TJOI2018 游园)。因此我们需要想办法将其转化为求和的形式,这时候就要找到它的等价表达。类似的题目还有 CF1067E Random Forest Rank。
const int MAXN=5000;
const int INV2=MOD+1>>1;
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,ipw2[MAXN*MAXN+5],dp[MAXN+5][MAXN+5],res=0,siz[MAXN+5];
link_list<int,MAXN,MAXN*2> g;
void dfs(int x,int f){
dp[x][0]=dp[x][1]=INV2;siz[x]=1;
for(int e=g.hd[x];e;e=g.nxt[e]){
int y=g.val[e];if(y==f) continue;dfs(y,x);
static int tmp[MAXN+5];memset(tmp,0,sizeof(tmp));
for(int i=1;i<=siz[x];i++) for(int j=0;j<=siz[y];j++){
tmp[i+j]=(tmp[i+j]+1ll*dp[x][i]*dp[y][j]%MOD*ipw2[2*i*j])%MOD;
tmp[0]=(tmp[0]+1ll*dp[x][i]*dp[y][j]%MOD*(1-ipw2[2*i*j]+MOD))%MOD;
} siz[x]+=siz[y];for(int i=1;i<=siz[x];i++) dp[x][i]=tmp[i];
dp[x][0]=(dp[x][0]+tmp[0])%MOD;
} res=(res+dp[x][0])%MOD;//printf("%d %d\n",x,dp[x][0]);
}
int main(){
freopen("thousands.in","r",stdin);
freopen("thousands.out","w",stdout);
scanf("%d",&n);
for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),g.ins(u,v),g.ins(v,u);
for(int i=(ipw2[0]=1);i<=n*n;i++) ipw2[i]=1ll*ipw2[i-1]*INV2%MOD;
dfs(1,0);printf("%d\n",1ll*res*qpow(2,n*n)%MOD);
return 0;
}
NFLSOJ #10317. -「2020联考北附2」三千世界(找等价表达+树形 dp)的更多相关文章
- [多校联考2019(Round 5 T1)] [ATCoder3912]Xor Tree(状压dp)
[多校联考2019(Round 5)] [ATCoder3912]Xor Tree(状压dp) 题面 给出一棵n个点的树,每条边有边权v,每次操作选中两个点,将这两个点之间的路径上的边权全部异或某个值 ...
- [多校联考2019(Round 5 T3)]青青草原的表彰大会(dp+组合数学)
[多校联考2019(Round 5)]青青草原的表彰大会(dp+组合数学) 题面 青青草原上有n 只羊,他们聚集在包包大人的家里,举办一年一度的表彰大会,在这次的表彰大会中,包包大人让羊们按自己的贡献 ...
- Luogu4363 [九省联考2018]一双木棋chess 【状压DP】【进制转换】
题目分析: 首先跑个暴力,求一下有多少种状态,发现只有18xxxx种,然后每个状态有10的转移,所以复杂度大约是200w,然后利用进制转换的技巧求一下每个状态的十进制码就行了. 代码: #includ ...
- noi省选 [九省联考2018]一双木棋题解(状压dp)
比浙江简单多了........ 题目转送:https://www.luogu.org/problemnew/show/P4363 分析: 我们注意到n和m都很小,考虑一下状压dp. 显然,棋子摆成的形 ...
- 洛谷P4363 [九省联考2018]一双木棋chess 【状压dp】
题目 菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束. 落子的规则是:一个格子可以落子当且仅当这个 ...
- loj2542 「PKUWC2018」随机游走 【树形dp + 状压dp + 数学】
题目链接 loj2542 题解 设\(f[i][S]\)表示从\(i\)节点出发,走完\(S\)集合中的点的期望步数 记\(de[i]\)为\(i\)的度数,\(E\)为边集,我们很容易写出状态转移方 ...
- loj#2542. 「PKUWC2018」随机游走(树形dp+Min-Max容斥)
传送门 首先,关于\(Min-Max\)容斥 设\(S\)为一个点的集合,每个点的权值为走到这个点的期望时间,则\(Max(S)\)即为走遍这个集合所有点的期望时间,\(Min(S)\)即为第一次走到 ...
- BZOJ2591/LG3047 「USACO12FEB」Nearby Cows 换根树形DP
问题描述 BZOJ2591 LG3047 题解 换根树形DP. 设 \(opt[i][j]\) 代表 当 \(1\) 为根时,\(i\) 为根的子树中,到 \(i\) 的距离为 \(j\) 的权值和 ...
- LOJ 3124 「CTS2019 | CTSC2019」氪金手游——概率+树形DP
题目:https://loj.ac/problem/3124 看了题解:https://www.cnblogs.com/Itst/p/10883880.html 先考虑外向树. 考虑分母是 \( \s ...
随机推荐
- 【UE4 C++ 基础知识】<1> UPROPERTY宏、属性说明符、元数据说明符
属性声明 属性使用标准的C++变量语法声明,前面用UPROPERTY宏来定义属性元数据和变量说明符. UPROPERTY([specifier, specifier, ...], [meta(key= ...
- Java序列元素替换
1.数组 直接赋值. 2.String (1) String是不可变的,只能将新的字符串重新赋给String变量.可使用substring进行拼接: String s="hello" ...
- kivy Label触发事件
kivy label也可以触发事件,为什么只有我这么无聊学垃圾kivy """ 在通过ref标记一段文本后点击这段文本就可以触发'on_ref_press'事件,在该事 ...
- VS2019、Qt5.12及QGis3.16开发常见问题汇总
在C++.Qt软件开发过程中,常常遇到一些编译错误或警告:本文将VS2019.Qt5.12.10和QGis3.16.10的二次开发过程常见的问题做了整理,供大家参考,也便于日后查阅.该内容分为四部分: ...
- stm32驱动超声波模块
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发. #define HCSR04_PORT GPIOB #define HCSR04_CLK RCC ...
- 深度解析HashMap集合底层原理
目录 前置知识 ==和equals的区别 为什么要重写equals和HashCode 时间复杂度 (不带符号右移) >>> ^异或运算 &(与运算) 位移操作:1<&l ...
- Spring源码分析-BeanFactoryPostProcessor
Spring源码分析-BeanFactoryPostProcessor 博主技术有限,本文难免有错误的地方,如果您发现了欢迎评论私信指出,谢谢 BeanFactoryPostProcessor接口是S ...
- shell 中单引号和双引号的区别
用以下代码来说明: #!/bin/bash url="http://c.biancheng.net" website1='C语言中文网:${url}' website2=" ...
- Java测试开发--lambda函数式编程(六)
1.Lambda 表达式,是jdk1.8特性,接口里只有一个方法. 举例说明 // ()参数列表 ->连接符 {方法体} 经常在匿名对象 testPerson(()->{System.ou ...
- 添加su权限
在root用户下 visudo amy ALL=(ALL) NOPASSWD:ALL 在amy用户下 vim ~/.bashrc alias sd = "sudo"