Crystal
Crystal
颜色显然具有对称性,下文都只考虑其中一种情况,答案记得乘以二。
设每一个点到异色点的最短距离为 \(f(u)\),那么一组 \(f\) 与一种颜色状态一一对应。
尝试证明,必要性显然,考虑充分性。当且仅当相邻的两个点值同时为 \(1\) 时,两个点颜色不同,据此我们可以划分整棵树,从而确定颜色状态。
一组合法的 \(f(u)\) 需要满足以下条件:
-
对于任意的\(u\),使得\(f(u) \geq 1\)
-
对于任意相邻的\(u\),\(v\),使得\(| f(u) - f(v) | \leq 1\)。
-
对于任意的\(u\),存在一个相邻的\(v\),使得\(| f(u) - f(v) | = 1\)
-
当 \(f(u) = f(v) = 1\) 其中 \(u\),\(v\) 相邻时,\(u\),\(v\) 异色,不需要满足条件三。
接下来考虑 树形DP
,设 \(g(u,x,0/1)\) 表示以 \(u\) 为根的子树中,使得\(f(u) = x\),\(u\) 的儿子是或否令其满足条件三或条件四的答案。
明确一下要求的答案:
\(\sum s (\sum x) ^ k\),其中 \(s\) 指状态。
首先,转移过程中我们肯定需要以某种方式将各儿子的答案合并。
合并的结果为 \(\sum s (\sum x + \sum y) ^ k\)。
而我们只知道 \(\sum s (\sum x) ^ k\) 与 \(\sum s (\sum y) ^ k\)。
不妨将合并的结果通过二项式定理展开,这样,我们只记录 \(k \in [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];
}
}
}
表达能力不好,靠个人理解吧。