大龄选手只杀到 E,鉴定为寄。
思路
正解是高明数数,这里提供一种强行推导的方法。
首先有一个死掉的思路:原问题等价于求所有 \(n\) 个点的有标号无根树的直径之和。
如果有什么高明的数数方法可以做当然是好的,但是我不会。
所以我们考虑一个假定的度数序列所产生的直径。
结论:一个度数序列可以构造出树的充要条件是 \(\sum\limits_{i = 1}^n \operatorname{deg}(i) = 2n - 2\),可以构造出来。
对于一个和为 \(2n - 2\) 的序列,极端情况下肯定想构造出一条链。
但是因为存在度数大于等于 \(2\) 的结点,只能构造出一条以叶结点为端点的极长链,然后把剩下的叶结点挂在上面。
假设有 \(k\) 个叶结点,则极长链中包含所有非叶结点和 \(2\) 个作为端点的叶结点,一共有 \(n - k + 2\) 个结点,于是长度为 \(n - k + 1\).
根据结论,随意划分剩下的度数就行。考虑每种直径的贡献,可以插板法推出答案是:\(\sum\limits_{k = 1}^n {n \choose k} {n - 3 \choose n - k - 1} (n - k + 1)\).
有老哥用 NTT 硬草过掉了,比较震撼。
观察到 \(n - k - 1\) 和 \(n - k + 1\) 类似,考虑配凑一下:\(\sum\limits_{k = 1}^n {n \choose k} {n - 3 \choose n - k - 1} (n - k - 1) + 2 \sum\limits_{k = 1}^n {n \choose k} {n - 3 \choose n - k - 1}\).
前面的 \(n - k - 1\) 可以被组合数吸收:\((n - 3) \sum\limits_{k = 1}^n {n \choose k} {n - 4 \choose n - k - 2} + 2 \sum\limits_{k = 1}^n {n \choose k} {n - 3 \choose n - k - 1}\).
前后两项分别两个范德蒙德卷积,得到答案是 \((n - 3) {2n - 4 \choose n - 2} + 2 {2n - 3 \choose n - 1}\).
预处理一下阶乘逆元就可以 \(O(1)\) 算答案了。
代码
#include <cstdio>
using namespace std;
const int maxn = 2e6 + 5;
const int mod = 998244353;
int t, n;
int fac[maxn], invf[maxn];
void init(int lim)
{
fac[0] = invf[0] = fac[1] = invf[1] = 1;
for (int i = 2; i <= lim; i++) fac[i] = 1ll * fac[i - 1] * i % mod, invf[i] = 1ll * (mod - mod / i) * invf[mod % i] % mod;
for (int i = 2; i <= lim; i++) invf[i] = 1ll * invf[i - 1] * invf[i] % mod;
}
int C(int n, int m) { return (n < m ? 0 : 1ll * fac[n] * invf[m] % mod * invf[n - m] % mod); }
int main()
{
init(2e6);
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
printf("%d\n", (1ll * (n - 3) * C(2 * n - 4, n - 2) % mod + 2ll * C(2 * n - 3, n - 1) % mod) % mod);
}
return 0;
}
标签:结点,limits,int,题解,sum,Maximum,choose,ABC290F,2n
From: https://www.cnblogs.com/lingspace/p/abc290f.html