F2. Tree Cutting (Hard Version)

觀察:爲使相同顏色的節點處在同一個子樹中,則包含這些節點的最小子樹的所有節點必然會被劃分在同一部分。

因此,在隨意選擇一個節點作爲樹的根節點後,每種顏色的所有節點的LCA(最近公共祖先)必然也與這些節點在同一部分。

同時,我們也得到了無解判定:如果某兩種顏色的節點的最小子樹具有相同部分,則必定無解。

在判斷有解之後,我們可以把每種顏色對應的最小子樹縮成一個節點,則問題就轉化爲:

【一個n3×105n \leq 3\times 10^5個節點的樹,其中有kk個節點是被標記的,問有多少種方法把樹分成kk部分,每部分包含恰好一個被標記的節點。】

Step 2. 動態規劃

我們在縮點之後,只需要解決轉化後的問題。

f[x][s]f[x][s]表示以xx爲根的子樹有多少種劃分方式,使得xx所在的部分 【未包含s=0s=0 / 包含s=1s=1】 一個被標記的節點。

  1. xx未被標記,則

1.1. 若xx所在部分未包含被標記的節點,則對每個xx的兒子節點yy,若yy所在部分包含了被標記的節點,則必然不與xx在同一部分;若yy所在部分未包含被標記節點,則必然與xx在同一部分,因此有f[y][0]+f[y][1]f[y][0]+f[y][1]種可能。由乘法原理,有

f[x][0]=yson(x)(f[y][0]+f[y][1]). f[x][0] = \prod_{y \in \text{son}(x)} (f[y][0]+f[y][1]).

1.2. 若xx所在部分包含被標記的節點,則枚舉xx的兒子節點yy,其所在部分包含被標記節點,有f[y][1]f[y][1]種可能;對其他兒子節點zyz \neq y,若zz所在部分包含了被標記的節點,則必然不與xx在同一部分;若zz所在部分未包含被標記節點,則必然與xx在同一部分,因此有f[z][0]+f[z][1]f[z][0]+f[z][1]種可能。由乘法原理和加法原理,有

f[x][1]=yson(x)f[y][1]yzson(x)(f[z][0]+f[z][1]). f[x][1] = \sum_{y \in \text{son}(x)} f[y][1] \sum_{y \neq z \in \text{son}(x)} (f[z][0]+f[z][1]).

  1. xx被標記,則

2.1. xx所在部分不可能未包含被標記節點,即

f[x][0]=0, f[x][0] = 0,

2.2. 若xx所在部分包含被標記的節點,則對每個xx的兒子節點yy,若yy所在部分包含了被標記的節點,則必然不與xx在同一部分;若yy所在部分未包含被標記節點,則必然與xx在同一部分,因此有f[y][0]+f[y][1]f[y][0]+f[y][1]種可能。(這與1.1.的討論相同)由乘法原理,有

f[x][1]=yson(x)(f[y][0]+f[y][1]). f[x][1] = \prod_{y \in \text{son}(x)} (f[y][0]+f[y][1]).

總時間複雜度爲O(n)O(n)

原文:https://www.cnblogs.com/TinyWong/p/10422194.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章