Luogu5206 【WC2019】数树 【容斥,生成函数】

题目链接

第一问白给。

第二问:

\(b=y^{-1}\),且以下的 \(Ans\) 是除去 \(y^n\) 的。

\(C(T)\) 是固定了 \(T\) 中的边,再连 \(n-|T|-1\) 条边形成一棵树的方案数。设每个联通块的大小为 \(a_1,a_2,\ldots,a_{n-|T|}\),则答案为 \(n^{n-|T|-2}\prod a_i\)

证明可以使用 Matrix-Tree 定理。
\[ \begin{aligned}Ans&=\sum_{T_2}b^{|T_1\cap T_2|} \\&=\sum_S\sum_{T_2}b^{|S|}[T_1\cap T_2=S] \\&=\sum_S\sum_{T_2}b^{|S|}\sum_{S\subseteq T\subseteq T_1\cap T_2}(-1)^{|T|-|S|} \\&=\sum_{T\subseteq T_1}C(T)\sum_{S\subseteq T} b^{|S|}(-1)^{|T|-|S|} \\&=\sum_{T\subseteq T_1}C(T)(b-1)^{|T|} \\&=\sum_{T\subseteq T_1}(b-1)^{|T|}n^{n-|T|-2}\prod_{i=1}^{n-|T|}a_i \\&=n^{n-2}\sum_{T\subseteq T_1}(\frac{b-1}{n})^{|T|}\prod_{i=1}^{n-|T|}a_i \\\end{aligned} \]
\(v=\frac{b-1}{n}\),就是求 \(T_1\) 的每条边选或不选,权值是 \(v^{选的边个数}\times 每个联通块大小之积\),求 \(2^{n-1}\) 种情况的权值之和。

这是之前做过的一个经典的树d,设 \(f_i\) 表示只考虑 \(i\) 的子树的答案,\(g_i\)表示只考虑 \(i\) 的子树,并且不考虑 \(i\) 所在联通块的答案乘上 \(v\)
\[ \begin{aligned}f_u&=f_uf_v+g_uf_v+g_vf_u \\g_u&=g_u(f_v+g_v)\end{aligned} \]

int bas, f[N], g[N], head[N], to[N << 1], nxt[N << 1];
inline void adde(int a, int b){
    static int cnt = 0;
    to[++ cnt] = b; nxt[cnt] = head[a]; head[a] = cnt;
}
inline void dfs(int x, int fa = 0){
    f[x] = 1; g[x] = bas;
    for(Rint i = head[x];i;i = nxt[i]) if(to[i] != fa){
        dfs(to[i], x);
        f[x] = add((LL) f[x] * f[to[i]] % mod, add((LL) f[x] * g[to[i]] % mod, (LL) g[x] * f[to[i]] % mod));
        g[x] = (LL) g[x] * add(g[to[i]], f[to[i]]) % mod;
    }
}
inline void main(){
    if(y == 1){printf("%d\n", kasumi(n, n - 2)); return;}
    bas = (kasumi(y, mod - 2) - 1ll) * kasumi(n, mod - 2) % mod;
    for(Rint i = 1;i < n;i ++){
        int a, b; scanf("%d%d", &a, &b);
        adde(a, b); adde(b, a);
    }
    dfs(1);
    printf("%d\n", (LL) kasumi(n, n - 2) * kasumi(y, n) % mod * f[1] % mod);
}

第三问:
\[ \begin{aligned}Ans&=\sum_TC(T)^2\sum_Sb^{|S|}(-1)^{|T|-|S|} \\&=\sum_TC(T)^2(b-1)^{|T|} \\&=\sum_T(b-1)^{|T|}n^{2n-2|T|-4}\prod a_i^2 \\&=\frac{(b-1)^n}{n^4}\sum_T(\frac{n^2}{b-1})^{n-|T|}\prod a_i^2 \\\end{aligned} \]
\(v=\frac{n^2}{b-1}\),于是就变成了,把这 \(n\) 个点分成一些联通块,设大小是 \(a\),每个联通块的权值是 \(va^2\times a^{a-2}=va^a\),求权值之积之和。
\[ \begin{aligned}Ans&=n^{-4}(b-1)^nn!\sum_{\sum a_i=n}\frac{a^av}{a!} \\F&=\sum_{k\ge 1}\frac{vk^kx^k}{k!} \\Ans&=n^{-4}(b-1)^nn![x^n]\exp(F)\end{aligned} \]

// 以上省略贼长的板子
inline void main(){
    if(y == 1){printf("%d\n", kasumi(n, 2 * n - 4)); return;}
    init(n);
    int p = kasumi(y, mod - 2) - 1, b = (LL) n * n % mod * kasumi(p, mod - 2) % mod;
    for(Rint i = 1;i <= n;i ++)
        A[i] = (LL) b * kasumi(i, i) % mod * invf[i] % mod;
    poly_Exp(A, n + 1);
    printf("%d\n", (LL) Exp[n] * kasumi(n, mod - 5) % mod * fac[n] % mod * kasumi((LL) y * p % mod, n) % mod);
}

猜你喜欢

转载自www.cnblogs.com/AThousandMoons/p/12061067.html
今日推荐