LOJ6733 人造情感 / 3.14 校內考試 靈活性(flexibility)
給你一顆 \(n\) 個節點的樹,以及 \(m\) 條路徑 \((u, v, w)\),其中 \(w\) 可以認為是 \((u, v)\) 這題路徑被標記的一個權值。一個路徑集合 \(S\) 的重量 \(W(S)\) 記為:找出 \(S\) 的一個權值之和最大的子集,該子集滿足任何兩條路徑沒有公共點,這個子集的所有路徑權值之和就是 \(W(S)\)。
記 \(f(u, v) = w\) 為最小的非負整數 \(w\),使得對於給定的 \(m\) 條邊組成的路徑集合 \(U\),\(W(U \cup \{(u, v, w + 1)\}) > W(U)\) 。
請你計算下式,對 \(998244353\)
取模。 \[\sum_{u=1}^n \sum_{v=1}^n f(u, v) \]\(n \le 3 \times 10^5, 0 \le m \le 3\times 10^5, 1 \le w \le10^9\)。
資料結構
動態規劃
首先考慮怎麼計算 \(W(U)\),我們可以設 \(f(x)\) 表示僅考慮 \(x\) 為根的子樹,不管 \(x\) 的選擇情況的最大權值,\(g(x)\) 表示僅考慮 \(x\) 為根的子樹,\(x\) 必須是空的收益,然後我們可以設 \(c(x) = g(x) - f(x)\) 表示把 \(x\) 空出來的代價,然後有轉移:
\[\begin{cases} g(x) = \sum_{y \in son_x} f(x)\\ f(x) = g(x) + \max_{\mathrm{lca}(u_i, v_i) = x}\{\sum_{k \in \mathrm{path}(u_i, v_i)} c_k\} \cup \{0\} \end{cases} \]然後 \(c(x)\)
接著考慮 \(W(U \cup \{u, v, w +1\})\) 怎麼求,那麼如果 \(\mathrm{lca}(u, v) = 1\),那麼答案就是 $f(1)+ \sum_{k \in \mathrm{path}(u, v)} c_k $。
但是如果不滿足上面的條件,令 \(t = \mathrm{lca}(u, v)\),那麼就可能會存在一條路徑使得其從上面經過了 \(t\),然後我們要將貢獻消除,於是我們可以設 \(h(x)\)
第一個轉移顯然可以直接賦值,第二個轉移,我們要考慮在一條路徑 \((u_i, v_i)\) 上面打上 \(h(x) + \sum_{k\in \mathrm{path}(u_i, v_i)} c_k + w_i\) 的標記,然後將它傳下去取 \(\max\),同時有不能傳到路徑上面的點。
如果是暴力,可以考慮每個點維護一個 tuple(w, a, b)
表示權值為 \(w\) 的 tag
,並且不能傳到 \(a, b\) 兩個兒子(如果沒有這麼多限制,直接賦值為 \(0\) 即可),然後將所有標記 sort
一遍,對於每個點暴力從大到小掃一遍,直到找到第一個滿足條件的最大的,因為每個標記最多被掃到 \(2\) 遍,因此複雜度為 \(\mathcal O(\sum 標記之和)\) 的。
然後我們可以使用線段樹 + 樹剖優化這個過程,因為很多標記都是賦值為 \((w, 重兒子, 0)\) 的形式,因此可以樹剖維護對於每個點,這種標記的最大值(也就是這種標記中只取最大的一個),每次操作只有重鏈頂端要單獨賦值,於是總的標記個數就是 \(\mathcal O(m \log n + n)\) 的了。
求出 \(h(x)\) 之後,對於 \((u, v)\) 的答案就是 \(f(1) - \left(h(\mathrm{lca}(u, v)) + \sum_{k \in \mathrm{path}(u, v)} c_k\right)\) 了,後面的式子就是在滿足 \(\{u, v \}\) 所在聯通塊沒有被佔領的情況下的最大值,那麼答案就是這個式子了。
具體細節看程式碼。