Crystal

Crystal

颜色显然具有对称性,下文都只考虑其中一种情况,答案记得乘以二。

设每一个点到异色点的最短距离为 f(u),那么一组 f 与一种颜色状态一一对应。

尝试证明,必要性显然,考虑充分性。当且仅当相邻的两个点值同时为 1 时,两个点颜色不同,据此我们可以划分整棵树,从而确定颜色状态。

一组合法的 f(u) 需要满足以下条件:

  1. 对于任意的u,使得f(u)1

  2. 对于任意相邻的uv,使得|f(u)f(v)|1

  3. 对于任意的u,存在一个相邻的v,使得|f(u)f(v)|=1

  4. f(u)=f(v)=1 其中 uv 相邻时,uv 异色,不需要满足条件三。

接下来考虑 树形DP,设 g(u,x,0/1) 表示以 u 为根的子树中,使得f(u)=xu 的儿子是或否令其满足条件三或条件四的答案。

明确一下要求的答案:

s(x)k,其中 s 指状态。

首先,转移过程中我们肯定需要以某种方式将各儿子的答案合并。

合并的结果为 s(x+y)k

而我们只知道 s(x)ks(y)k

不妨将合并的结果通过二项式定理展开,这样,我们只记录 k[0,3] 下的所有答案即可。

接下来,细看转移方程。

乘法即二项式定理合并。

总的思路就是枚举儿子人后不断合并。

实在不知道怎么讲了,看代码吧。

for(int u=n;u>=1;u--){//枚举父亲,倒序枚举省去DFS
for(int x=1;x<=n;x++){
f[u][x][0].Init(x);//初始化
f[u][x][1].Init(0);
for(int v:E[u]){//枚举儿子
tmp[0].Init(0);//临时变量
tmp[1].Init(0);
for(int y=max(1ll,x-1);y<=min(x+1,n);y++){//满足条件二
if(y==x+1){//父亲可以令儿子满足条件三,儿子可以取0或1
tmp[0]+=(f[v][y][0]+f[v][y][1])*f[u][x][0];
tmp[1]+=(f[v][y][0]+f[v][y][1])*f[u][x][1];
//只需要有一个儿子使父亲满足即可,所以仍然选择合并。
//因为这一项初始值为0所以排除了全部儿子都不能使父亲满足的情况
}
else if(y==x-1){//儿子可以令父亲满足条件三,父亲可以取0或1
tmp[1]+=f[v][y][1]*(f[u][x][1]+f[u][x][0]);
}
else{//互不能使满足条件三,儿子必须靠孙子满足条件三
tmp[0]+=f[v][y][1]*f[u][x][0];
tmp[1]+=f[v][y][1]*f[u][x][1];
if(x==1&&y==1){//u,v颜色不同,可以任意取,条件四满足
tmp[1]+=(f[v][y][0]+f[v][y][1])*(f[u][x][1]+f[u][x][0]);
}
}
}
f[u][x][0]=tmp[0];//赋值
f[u][x][1]=tmp[1];
}
}
}

表达能力不好,靠个人理解吧。

代码链接

posted @   DeepSeaSpray  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示