注意类似题目这种建树的方式,建出来可能是树,也可能是堆,而前者不一定是连续的编号,后者一定是连续的编号,这就导致了后者左右子树中一个是完全二叉树,另一个不是完全二叉树(这里就要利用这个性质优化时间复杂度)
显然考虑贡献,设
s
i
,
j
=
x
s_{i,j}=x
si,j=x,我们挑出两个点作为路径的起点和终点,然后算这条路径的
s
=
x
s=x
s=x的数量,但是发现算不出来,因为缺少长度,所以我们引入长度,假设这个路径的长度为
y
y
y,那么方案数显然就是
x
y
−
(
x
−
1
)
y
x^y-(x-1)^y
xy−(x−1)y;而除了这条路径的其余
n
−
y
n-y
n−y个点,染色方案数为
m
n
−
y
m^{n-y}
mn−y;假设整棵树长度为
y
y
y的路径有
k
y
k_y
ky个,那么
x
x
x对答案的贡献就是
∑
y
=
1
MAXL
m
n
−
y
(
x
y
−
(
x
−
1
)
y
)
k
y
x
\overset{\text{MAXL}}{\underset{y=1}{\sum}}m^{n-y}(x^y-(x-1)^y)k_yx
y=1∑MAXLmn−y(xy−(x−1)y)kyx
(其中
MAXL
\text{MAXL}
MAXL为最长路径,这个需要分类讨论),所以答案就为
∑
x
=
1
m
∑
y
=
1
MAXL
m
n
−
y
(
x
y
−
(
x
−
1
)
y
)
k
y
x
\overset{m}{\underset{x=1}{\sum}}\overset{\text{MAXL}}{\underset{y=1}{\sum}}m^{n-y}(x^y-(x-1)^y)k_yx
x=1∑my=1∑MAXLmn−y(xy−(x−1)y)kyx
,考虑到
k
y
k_y
ky与
x
x
x无关且
MAXL
\text{MAXL}
MAXL很小,所以交换美剧顺序,有
∑
y
=
1
MAXL
k
y
∑
x
=
1
m
m
n
−
y
(
x
y
−
(
x
−
1
)
y
)
x
\overset{\text{MAXL}}{\underset{y=1}{\sum}}k_y\overset{m}{\underset{x=1}{\sum}}m^{n-y}(x^y-(x-1)^y)x
y=1∑MAXLkyx=1∑mmn−y(xy−(x−1)y)x
所以现在的当务之急是计算
k
y
k_y
ky。unordered_map
好像不能使用pair
,所以我们用数组来DP(而不是用unordered_map
)
设 g [ i ] [ j ] g[i][j] g[i][j]表示从根节点往下走了 i i i层(每一层走的方向是确定的,我们都会向非完全二叉树的方向走;当然有时两个子树都是非完全二叉树,比如 n = 11 n=11 n=11,此时我们向右走),以当前节点为子树,长度为 j j j的总方案数; h [ i ] h[i] h[i]表示从根节点往下走了 i i i层,以当前节点为子树,这棵子树的深度(从 0 0 0开始计数)
计算 g [ i ] [ j ] g[i][j] g[i][j]的时候,我们已经计算好了 g [ i + 1 ] g[i+1] g[i+1],所以 g [ i ] [ j ] + = g [ i + 1 ] [ j ] g[i][j]+=g[i+1][j] g[i][j]+=g[i+1][j]; g [ i ] [ j ] g[i][j] g[i][j]还要加上完全二叉树的这棵子树的贡献,这个比较容易计算,设 G [ i ] [ j ] G[i][j] G[i][j]表示深度为 i i i的完全二叉树,长度为 j j j的总路径数,推导见代码,于是 g [ i ] [ j ] + = G [ h [ i ] − 1 ] [ j ] g[i][j]+=G[h[i]-1][j] g[i][j]+=G[h[i]−1][j](假设右子树是非完全二叉树,左子树是非完全二叉树的情况有一点点小的改变,但是道理一样);接下来只需要计算经过经过当前根节点的路径就好了,这样的路径又分为两类,一类是根节点为端点,另一类是根节点为中转点。对于前者非常好计算,后者需要枚举一颗子树的长度(为了方便枚举非完全二叉树的长度)然后计算出另一颗子树的长度
时间复杂度为 O ( ∑ m log n + T log 3 n ) O(\sum m\log n+T\log^3 n) O(∑mlogn+Tlog3n)