[題解][P5206][WC2019] 數樹 (op = 1)
簡要題意
給定 \(n, y\)。
一張圖有 \(|V| = n\) 個點,現在給出兩棵樹 \(T_1=G(V, E_1)\) 和 \(T_2=G(V, E_2)\)。
定義這兩棵樹的權值 \(F(E_1, E_2)\) 為 \(y\) 的 \(G'=(V,E_1\cap E_2)\) 的聯通塊個數次方。
即 \(F(E_1, E_2) = y^{n - |E_1\cap E_2|}\),給定 \(E_1\),計算 \(\sum_{E_2} F(E_1, E_2)\)。
其中 \(n\le 10^5\)。答案對 \(998244353\) 取模。
解題思路
首先我們要找到一個合適的形式來表示我們的答案,部分列舉 \(S=E_1\cap E_2\)
其中 \(S=E_1\cap E_2\) 這個恰好的條件限制較強,考慮容斥將限制弱化為 \(S\subseteq E_1\cap E_2\).
不妨考慮這樣一個容斥原理的式子:
\[f(S)=\sum_{T\subseteq S}\sum_{P\subseteq T}(-1)^{|T|-|P|}f(P) \]代入到原來的式子中,得到:
\[\begin{aligned} &\sum_{E_2} \sum_{S=E_1\cap E_2} y^{n-|S|}\\ =&\sum_{E_2} \sum_{T\subseteq E_1\cap E_2} \sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\ =&\sum_{T\subseteq E_1}g(T)\sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\=&\sum_{T\subseteq E_1}g(T)y^{n-|T|}\sum_{P\subseteq T}(-y)^{|T|-|P|}\\ =&\sum_{T\subseteq E_1}g(T)\sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\=&\sum_{T\subseteq E_1}g(T)y^{n-|T|}\sum_{|P|=0}^{|T|}\binom{|T|}{|P|}(-y)^{|T|-|P|}\\ =&\sum_{T\subseteq E_1}g(T)\sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\=&\sum_{T\subseteq E_1}g(T)y^{n-|T|}(1-y)^{|T|}\\ \end{aligned} \]其中 \(g(T)\)
假設 \(G=(V,T)\) 為一個由 \(k\) 個大小分別為 \(a_i\) 的連通塊組成的森林,則:
\[g(T)=n^{k-2}\prod_{i=1}^ka_i \]繼續代入 (注意到 \(n=|T|+k\) ),得:
\[\begin{aligned} &\sum_{T\subseteq E_1}g(T)y^{n-|T|}(1-y)^{|T|}\\ =&\sum_{T\subseteq E_1}n^{k-2}\prod_{i=1}^ka_i\ y^k(1-y)^{n-k}\\ =&\frac{(1-y)^n}{n^2}\sum_{T\subseteq E_1}\prod_{i=1}^k\frac{ny}{1-y}\ a_i \end{aligned} \]即一個大小為 \(a\)
據此可以容易得到一個 \(O(n^2)\) 的 DP,\(f(x,i)\) 表示 \(x\) 的子樹中,\(x\) 所在的連通塊大小為 \(i\) 的答案。
考慮到這個貢獻可以拆分表示為 \(\prod_{i=1}^k(K+K+K+\cdots K)\),故合併兩個大小分別為 \(x,y\) 的連通塊時,新的貢獻其實就是 \(K(x+y)\prod_{i\ne now}Ka_i\).
這樣狀態可以優化為 \(f(x,0/1)\) 表示 \(x\) 的子樹中,當前連通塊是否已經做出貢獻。
那麼轉移就是 (前面是選邊 \((x,y)\),後面是不選):
\[\begin{aligned} &f(x,1)=f(x,1)f(y,1)\ +\ f(x,1)f(y,0)+f(x,0)f(y,1)\\ &f(x,0)=f(x,0)f(y,1)\ +\ f(x,0)f(y,0) \end{aligned} \]程式碼
void dfs(int x, int fx){
siz[x] = 1, f[x] = coef, g[x] = 1;
for(int i = head[x]; i; i = e[i].nx){
int y = e[i].to; if(y == fx) continue;
dfs(y, x);
int sum = Mod((LL) f[x] * g[y] % mod + (LL) g[x] * f[y] % mod - mod);
MOD(f[x] = (LL) f[x] * f[y] % mod + sum - mod);
MOD(g[x] = (LL) g[x] * f[y] % mod + (LL) g[x] * g[y] % mod - mod);
}
}
void solve(){
coef = (LL) n * y % mod * qpow(1 - y + mod) % mod;
dfs(1, 0);
cout << (LL) f[1] * qpow(1 - y + mod, n) % mod * qpow((LL) n * n % mod) % mod << endl;
}