题意
给定一棵树,问多少个排列使得每个长为 m m m 的子区间内的点的导出子图是连通的,答案对 1 0 9 + 9 10^9+9 109+9 取模。 2 ≤ m ≤ n ≤ 400 2\leq m\leq n\leq 400 2≤m≤n≤400。
题解
考虑两种情况:
- 2 m ≤ n 2m\leq n 2m≤n;
- 2 m > n 2m>n 2m>n。
2 m ≤ n 2m\leq n 2m≤n
此时排列的最前 m m m 个元素一定是一棵子树,中间部分在一条链上,最后 m m m 个元素在另一个子树里。显然以重心为根 DFS 时,如果恰有两棵大小为 m m m 的子树且中间是一条 链连接则有方案,方案数即为两棵树分别的拓扑序数量之积乘以 2(从 A 到 B 或从 B 到 A)。 2 m = n 2m=n 2m=n 的情况比较特殊:重心有一个大小为 m m m 的子树、重心与其他子树的大小之和为 m m m。
2 m > n 2m>n 2m>n
此时点可以分为三部分:一部分是前 n − m n-m n−m 个点,它们会在开始时算到长为 m m m 的区间中,最后退出这个区间;一部分是最后 n − m n-m n−m 个点,它们会在开始时不在区间中、最后进入这个区间;最后一部分是中间的点,它们自始至终都在区间中。
显然:
- 重心会在第三部分,因为它没有一棵子树能塞下大小为 m m m 的连通块;
- 第一、二部分会是很多子树,且它们之间没有交;第三部分是围着重心的一个连通块。
以重心为根,开始 DP。记 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k] 为以 i i i 为根的子树中, i i i 确定为第三部分、有 j j j 个节点在第一部分、 k k k 个在第二部分;转移时枚举子树的 j j j、 k k k,额外考虑整棵子树都属于第一部分或第二部分的情况转移。这样做是 O ( n 4 ) O(n^4) O(n4) 的。
于是有一个树上背包的常见 trick:假如我们强制要求某个节点选了某个条件之后,这个点的子树全都必须选这个条件,我们可以在 DFS 序上 DP 转移。对于这道题,记 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k] 为已经确定了 DFS 序小于 i i i 的所有节点、其中第一部分、第二部分分别有 j , k j,k j,k 个的方案数 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k] 可以转移到 f [ i + 1 ] [ j ] [ k ] f[i+1][j][k] f[i+1][j][k](将第 i i i 个归入第三部分)、 f [ i + s z [ i d [ i ] ] ] [ j + s z [ i d [ i ] ] ] [ k ] f[i+sz[id[i]]]\ [j+sz[id[i]]]\ [k] f[i+sz[id[i]]] [j+sz[id[i]]] [k](将第 i i i 个及其子树归入第二部分)、 f [ i + s z [ i d [ i ] ] ] [ j ] [ k + s z [ i d [ i ] ] ] f[i+sz[id[i]]]\ [j]\ [k+sz[id[i]]] f[i+sz[id[i]]] [j] [k+sz[id[i]]](将第 i i i 个及其子树归入第三部分)。
时间复杂度 O ( n 3 ) O(n^3) O(n3)。